This is following a renaming of registerInputFrame to handleInputFrame.
- queueInputBitmap is renamed to handleInputBitmap for consistency with
handleInputFrame.
- registerInputStream is renamed to onInputStreamChanged for consistency
with media3 method names.
PiperOrigin-RevId: 655529699
Aligns `MediaExtractorCompat` with platform behavior by using `getDeclaredLength()`
instead of `getLength()` when setting the data source. This ensures compatibility
with asset files where the length is not predefined, even though it may result
in reading across multiple logical files when backed by the same physical file.
PiperOrigin-RevId: 655153390
AudioTrack automatically ramps down volume when pausing. However,
when this happens as part of a AudioSink.flush() operation, we
need to postpone the actual flush() until the ramp down finished
in the audio system. Otherwise audio is just cut off, creating pop
sounds.
Delaying the release is fine now, because DefaultAudioSink starts
creating a new track immediately without waiting for the previous
track to be released.
Also using the opportunity to add more comments about related quirks
of the AudioTrack flush/release handling for more context.
PiperOrigin-RevId: 654794818
We currently wait until a previous AudioTrack from the same
DefaultAudioSink is released on a background thread before attempting
to initialize a new AudioTrack. This is done to avoid issues where
the releasing track blocks some shared audio memory, preventing a new
track from being created.
The current solution has two main shortcomings:
- In most cases, the system can easily handle multiple AudioTracks
and waiting for the release just causes unnecessary delays (e.g.
when seeking).
- It only waits for a previous track from the same DefaultAudioSink,
not accounting for any other tracks that may be in the process of
being released from other players.
To improve on both shortcomings, we can
(1) move the check for "is releasing tracks and thus may block shared
memory" to the static release infrastructure to be shared across all
player instances.
(2) optimistically create a new AudioTrack immediately without waiting
for the previous one to be fully released.
(3) extend the existing retry logic that already retries failed
attempts for 100ms to only start the timer when ongoing releases are
done. This ensures we really waited until we have all shared resources
we can get before giving up completely. This also acts as a replacement
for change (2) to handle situations where creating a second track is
genuinely not possible. Also increase threshold to 200ms as the new
unit test is falky on a real device with just 100ms (highlighting that
the device needed more than 100ms to clean up internal resources).
PiperOrigin-RevId: 654053123
Introduced three `setDataSource` APIs in `MediaExtractorCompat`, enabling the use of `AssetFileDescriptor` and `FileDescriptor` to set the data source.
PiperOrigin-RevId: 653957035
This controller connects the audio output to the MediaCodec so
that it can automatically propagate CTA-2075 loudness metadata.
PiperOrigin-RevId: 653628503
This replaces the existing PlaceholderSurface mode with a more
efficient solution that doesn't require a GL texture or a new
thread.
PiperOrigin-RevId: 653537596
This is a regression test for the bug introduced in bb9ff30c3a
which was manually spotted and fixed in 0d2bf49d6a.
Reverting the fix causes this test to fail.
This test is a bit hacky because we have to munge the stack trace of
the `IllegalStateException` to make it look like it was thrown from
inside `MediaCodec`. We deliberately do this 'badly' (e.g. using
`fakeMethod`) to avoid a future reader being confused by a
fake-but-plausible stack trace.
PiperOrigin-RevId: 652820878
Now the value is guaranteed to be zero (see bb9ff30c3a), we can
remove the rotation handling for it in the UI module. We can also
enforce the documentation more clearly by not even setting the
value to anything other than zero.
PiperOrigin-RevId: 652772091
Added a method to set the timeout for the SNTP request.
Also changed the default timeout to 5s instead of 10s as it seemed quite high.
Issue: androidx/media#1540
PiperOrigin-RevId: 652566008
The change in bb9ff30c3a removed the detection util completely,
but even on API21+, the codec exceptions can be thrown as
IllegalStateException and we should reinstate this check to
correctly classify the exceptions.
PiperOrigin-RevId: 652557091
This removes several workarounds that are no longer needed, including
`codecNeedsMonoChannelCountWorkaround` which has been permanently
disabled since the (incomplete) minSdk 19 clean-up in fb7438378d.
PiperOrigin-RevId: 652495578
This should have no influence on app behavior and other policies
and just allows code to depend on new API 35 platform symbols.
PiperOrigin-RevId: 652414026
We currently use displaySurface == placeholderSurface IF codec != null
as a signal that the codec is configured with a placeholder. In the
future, this placeholder might not be needed and we can decouple this
state a bit better by leaving displaySurface == null in this case and
only using placeholderSurface instead of null when setting a Surface
to the codec.
PiperOrigin-RevId: 652391729
All other AndroidX libraries have already increased their min SDK to
21.
This change renames private symbols to remove `V21` suffixes and
similar, but doesn't change public or protected symbols with similar
names, to avoid needless breakages/churn on users of the library.
Some of the dead code removal is more complex, so I've split it out
into follow-up changes to make it easier to review.
PiperOrigin-RevId: 651776556
MediaCodecRenderer might not be able to determine whether a sample
is last in time. Do not use decoder input skipping optimization
for buffers close to media end duration in order to ensure
last frame is rendered.
PiperOrigin-RevId: 651757814
The integration with `SubtitleTranscodingExtractorOutput` has been
moved inside the relevant `Extractor` implementations instead.
PiperOrigin-RevId: 651213564
VideoSink.registerInputFrame is now called for every input frame (not
only the ones that should be rendered to the input surface) because it's
the VideoSink that decides whether it wants the frame to be rendered.
PiperOrigin-RevId: 651049851
In order for DASH playback to benefit from
FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES, the fMP4 extractor flag
must be set. The smallest API change that allows this is to add an
experimental method to BundledChunkExtractor.
Add a dash end-to-end test to verify that video frames are skipped at
decoder input.
PiperOrigin-RevId: 651046676
The operation almost always acquires resources straight-away,
for example a new thread or file access. This means starting
many metadata retrievals in parallel easily causes resource
contention. This problem can be alleviated by limiting the
maximum number of parallel retrievals.
Local testing showed a 20% speedup for local file retrievals
when limited to 5 in parallel. Any more parallel retrievals
did not show any improvement or started getting slower again
the more operations are allowed.
PiperOrigin-RevId: 650674685
MetadataRetriever is often used in a loop to retrieve data about many
items in a directory for example. In such cases, it's wasteful to
start a new 'playback' thread for each retrieval, in particular since
this thread is doing almost nothing (just triggering loads and handling
events). This change re-uses an existing thread if one exists already.
PiperOrigin-RevId: 650633343
During a seek, or when playing a media with clipped start,
MCVR encounters preroll decode-only buffers that are not rendered.
Use C.BUFFER_FLAG_NO_OTHER_SAMPLE_DEPENDS_ON_THIS to determine
whether a decode-only buffer is unused as reference.
These buffers can be dropped before the decoder.
When this optimization is triggered, increment
decoderCounters.skippedInputBufferCount.
Tested in ExoPlayer demo app on "One hour frame counter (MP4)"
after enabling extractorsFactory.setMp4ExtractorFlags(
FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES);
Observe: "sib" increases on each seek.
PiperOrigin-RevId: 650566216
The idea was to not even write any samples to SampleQueues as
they are not needed during the metadata extraction process.
However, this is not easily possible as long as we use our
existing Extractors and MediaSource/Periods for loading given
how deeply ingrained the extraction of samples is in these
classes. For most common formats like MP4, no samples will be
extracted anyway as they can finish the prepare step without
reading any samples.
PiperOrigin-RevId: 650529371
Upon the call of `PreloadMediaSource.preload`, the source will periodically check the source refresh or period loading error, and trigger `PreloadMediaSource.PreloadControl.onPreloadError`. For now, the `DefaultPreloadManager` will skip the problematic source and continue to preload the next source. The checking of the error will be terminated when the source stops preloading or releases.
PiperOrigin-RevId: 650195817
The percentage should be interpreted as relative to the size of a parent
node.
This change makes this inheritance work correctly for percentages in
both the parent and child. It does not fix the case of a non-percentage
parent size with a percentage child size.
PiperOrigin-RevId: 649631055
Parse LHEVCDecoderConfigurationRecord with the ‘lhvC’ type and set the corresponding sample mime type to video/mv-hevc. With no MV-HEVC decoder available, fallback to single-layer HEVC decoding.
PiperOrigin-RevId: 649119173
The VideoSink has an input and an output surface. Clarify which surface
the Javadoc is referring to. Also document that the VideoSink can be fed
with images, and that multiple renderers can feed the same sink.
PiperOrigin-RevId: 649052551
MCVR crashed because MCVR registers a new input stream to VideoSink on every
`onOutputFormatChanged()`, assuming that `onOutputFormatChanged()` is only
invoked on media item transition. However, it can be called multiple times for
one media item.
PiperOrigin-RevId: 649050576
Lint somehow complains that the integer resulting from the bit-manipulation shouldn't be passed as an @IntDef parameter.
#cherrypick
PiperOrigin-RevId: 648687698
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
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
#cherrypick
PiperOrigin-RevId: 646968309
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
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
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
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
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
Summary:
This change aims to add a generic `CustomData` field to the `Format` class.
The intent is to allow ExoPlayer customers to add extra data to the Format class without forcing
specific data to be included, impacting customers that do not need it and would allow for the data
to be changed without requiring changes to the `Media3` codebase.
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
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
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
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
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
This method allows customizing the maximum position when using `Player.seekToPrevious()`.
This commit also adds two new methods to `TestExoPlayerBuilder`:
- `setMaxSeekToPreviousPosition(long)`
- `getMaxSeekToPreviousPosition()`
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
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
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
- 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
If subtitle-parsing-during-extraction is enabled (now defaults to on),
the 'outer' extractor class name is often
`SubtitleTranscodingExtractor`, leading to some slightly useless error
messages like:
`None of the available extractors (FragmentedMp4Extractor, Mp4Extractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, TsExtractor, MatroskaExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, AviExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor)`
PiperOrigin-RevId: 636834354
If MediaCodec allocates passes an image buffer with a cropped region,
SurfaceTexture.getTransformMatrix will cut off 2 pixels from each dimensions.
The resulting videos will appear a little stretched.
This patch inspects the SurfaceTexture transform matrix, and guesses what the
unscaled transform matrix should be.
Behind experimentalAdjustSurfaceTextureTransformationMatrix flag
PiperOrigin-RevId: 635721267
This case is most likely to happen when re-preparing a multi-period
live stream after an error. The live timeline can easily move on to
new periods in the meantime, creating this type of update.
The behavior before this change has two bugs:
- The player resolves the new start position to a subsequent period
that existed in the old timeline, or ends playback if that cannot
be found. The more useful behavior is to restart playback in the
same live item if it still exists.
- MaskingMediaSource creates a pending MaskingMediaPeriod using the
old timeline and then attempts to create the real period from the
updated source. This fails because MediaSource.createPeriod is
called with a periodUid that does no longer exist at this point.
We already have logic to not override the start position and need
to extend this to also not prepare the real source.
Issue: androidx/media#1329
PiperOrigin-RevId: 634833030
The two affected tests where playing until a specific
position to enable the player to read ahead. The method
pauses at exactly the target position, but then has
temporarily undetermined behavior because the playback
thread uses player.getClock().onThreadBlocked() that lets
the playback thread make progress in parallel to the test
thread. The tests were flaky because they sometimes made
so much progress that they ended playback before we could
query the updated renderer state.
This can be fixed by using
run(player).untilBackgroundThreadCondition instead, which
is guaranteed to be fully deterministic, but may not be able
to stop at exactly the desired position (which we don't
really need anyway for this test).
PiperOrigin-RevId: 634699752
The method is only allowed to be called on prepared items.
This check was currently missing and also causing the
corresponding test to be flaky in ExoPlayerTest.
PiperOrigin-RevId: 634694077
Before this change, if a playback error is thrown the test fails with a
timeout and no additional info:
```
java.util.concurrent.TimeoutException
at androidx.media3.exoplayer.e2etest.WebvttPlaybackTest.stallPlayerUntilCondition(WebvttPlaybackTest.java:361)
```
After this change, the test failure includes a much more useful stack
trace, e.g. from 0352db9a37:
```
Caused by: java.lang.IllegalStateException: Legacy decoding is disabled, can't handle text/vtt samples (expected application/x-media3-cues).
at androidx.media3.common.util.Assertions.checkState(Assertions.java:100)
at androidx.media3.exoplayer.text.TextRenderer.assertLegacyDecodingEnabledIfRequired(TextRenderer.java:587)
at androidx.media3.exoplayer.text.TextRenderer.onStreamChanged(TextRenderer.java:210)
```
PiperOrigin-RevId: 634672138
To override this change, and go back to parsing during rendering,
apps must make two method calls:
1. `MediaSource.Factory.experimentalParseSubtitlesDuringExtraction(false)`
2. `TextRenderer.experimentalSetLegacyDecodingEnabled(true)`
PiperOrigin-RevId: 634262798
The test currently resets the time too far in the past and then has
to run through ~30000 additional iterations of doSomeWork to reach
the end, sometimes triggering the test timeout.
Fix it by resetting the time to the intended start position when
transitioning items.
PiperOrigin-RevId: 633918706
This annotation is only needed on public classes.
This change also removes the `/* package */` comment from some `public`
classes.
PiperOrigin-RevId: 633864544
This means the content source is 'prepared' instantly with a
placeholder, enabling all further preparation steps (e.g. loading
preroll ads) while the actual content is still preparing. This
improvement can speed up the start time for prerolls in manifest-based
content that doesn't have a zero-time preparation step like progressive
media.
Issue: androidx/media#1358
PiperOrigin-RevId: 633640746
This allows apps to better detect when the platform
reclaims a codec. This requires adding the error code
to MediaCodecDecoderException.
PiperOrigin-RevId: 633588914
The class currently tracks the input format itself, updating it too
early in onConfigure() instead of onFlush(). This causes issues when
the format changes and the new values are applied to the silence
skipping logic of the old format. The fix is to use the base class
input format handling instead.
Issue: androidx/media#1352
PiperOrigin-RevId: 633232368
Due to loading a MediaSourceFactory via reflection:
Before this change
* the content type was logged as an integer, rather than a human-readable string
* `ClassNotFoundException` was swallowed silently by `maybeLoadSupplier` without telling the user what module they were missing
After:
* ClassNotFoundException is swallowed silently ONLY when determining supported types
* ClassNotFoundException is bubbled up when we are trying to play media without the corresponding module properly loaded
PiperOrigin-RevId: 632568989
The same doSomeWork iteration that triggers the silence skipping
discontinuity may already have another discontinuities (like
AUTO_TRANSITION), which should take precedence over the silence
skipping.
PiperOrigin-RevId: 632432851
When the period has loaded to the end of the source, the `period.getBufferedPositionUs` will be set to `C.TIME_END_OF_SOURCE`, which is a negative value. Thus, the original `continueLoadingPredicate` will never turn to `false`, as the `bufferedPositionUs` is definitely less than the target preload position that is expected to be positive.
In this change, we added `PreloadMediaSource.PreloadControl.onLoadedToTheEndOfSource(PreloadMediaSource)` to indicate that the source has loaded to the end. This allows the `DefaultPreloadManager` and the custom `PreloadMediaSource.PreloadControl` implementations to preload the next source or take other actions.
This bug was not revealed by the the `DefaultPreloadManagerTest` because the related tests were all using the `FakeMediaSource` and only setting the preload target to `STAGE_TIMELINE_REFRESHED`. Thus, the tests for testing the `invalidate()` behaviors were modified to use the real progressive media whenever possible, unless we have to use `FakeMediaSource` to squeeze a chance to do more operations between the preloading of sources to test some special scenarios.
PiperOrigin-RevId: 631776442
For offloaded playback, reset the tracking field for stream completion in `DefaultAudioSink` prior to calling `AudioTrack.stop()` so that `AudioTrack.StreamEventCallback#onPresentationEnded` correctly identifies when all pending data has been played.
#minor-release
PiperOrigin-RevId: 631744805
When the PlaybackParameters are set to their DEFAULT value, we
currently bypass the audio processor chain when determining the
output media position, under the assumption that no timestamp
change happens in the audio processors. This assumption may not
be true as the audio processors can change playout durations on
their own accord independent of the provided PlaybackParameters.
To correctly reflect any updated playout duration, we can just
always check the audio processor chain. The default implementation
will continue to assume that only the SonicAudioProcessor changes
the playout duration.
PiperOrigin-RevId: 631726112
Without it, the DAC doesn't render the full sentence. And the link is not actually linking to the proper constructors.
#minor-release
PiperOrigin-RevId: 630395271
Set `VideoSink`'s offset during seeking in `MCVR.onPositionReset()`
This one is necessary in some cases, where `onProcessedStreamChange()` is not
invoked during a seek. For example, when seeking when playback has ended.
PiperOrigin-RevId: 630056723
To find the column of an index in a matrix the formula "column = index % width" should be used, not "column = index % height"
If inputFormat.tileCountVertical was equal to 1 then it would not throw an error, but instead result in the first tile of the bitmap always being returned. If inputFormat.tileCountVertical was larger than 1 then Bitmap.createBitmap() would throw an error as it would attempt to go outside the bounds of outputBitmap
ImageRenderTest has been updated to test for 2x3 images so that tileCountVertical != tileCountHorizontal. These tests passed previously because they were equal, so using tileCountVertical produced the same results as tileCountHorizontal
The last rebuffer time was being updated erroneously, even in the absence of rebuffering events, resulting in incorrect `bs` (buffer starvation) key in CMCD.
Issue: androidx/media#1124
PiperOrigin-RevId: 629731796
These subtitles were skipped because they are marked as shouldBeSkipped
based on their timestamps. The fix removes this flag entirely in
SimpleSubtitleDecoder because TextRenderer handles potential skipping
if needed.
PiperOrigin-RevId: 629717970
`updateRebufferingState` is invoked immediately preceding this `if-else`, with no alteration of state occurring in between, making this invocation unnecessary.
PiperOrigin-RevId: 629694531
This lets apps update the task manager priority and send the
priority message to all renderers so that they can adjust their
resources if needed.
PiperOrigin-RevId: 629426058
This change adds a 'free-form' text genre to the existing
`bear-id3.mp3` sample, and adds a new sample with a 'numeric' genre ([9
is Metal](https://mutagen-specs.readthedocs.io/en/latest/id3/id3v2.4.0-frames.html#appendix-a-genre-list-from-id3v1)).
The samples were modified with:
```shell
$ id3edit --set-genre "Gorpcore" bear-id3.mp3
$ id3edit --set-genre "9" bear-id3-numeric-genre.mp3
```
Reading the numeric genre with `exiftool` shows the mapping back to
'Metal':
```
$ exiftool bear-id3-numeric-genre.mp3 | grep Genre
Genre : Metal
```
The playback dumps don't contain the genre because it's not yet
propagated to `MediaMetadata.genre`. That is done in a follow-up
change.
Issue: androidx/media#1305
PiperOrigin-RevId: 629043506
This removes a window of inconsistency between the timeline
known to the player and the most recent timeline in the
`MediaSourceList` by removing the `MSG_DO_SOME_WORK` when
sending `MSG_PLAYLIST_UPDATE_REQUESTED`. `MSG_DO_SOME_WORK`
is then sent again when the playlist update is requested.
PiperOrigin-RevId: 629021752
Some test cases are still using `ConcatenatingMediaSource`
even if they do not test specific features of the concatenating
source. Apparently these test have a slightly different timing
behavior when it comes to updating the `MediaPeriodQueue` and
emitting change events with analytics.
Using the playlist API ensures testing the future-proof code path.
PiperOrigin-RevId: 628413460
The first has a string genre, and various other values set, generated
from `sample.mp4` with the command below [1].
The second has a numeric genre, to test `gnre` atom parsing. This
parsing is currently broken, the fix is in a follow-up change. This
file was also generated from `sample.mp4` with the command below [2].
This change also includes `CommentFrame.text` in its `toString`
representation, otherwise there's no difference between e.g. different
levels of `ITUNESADVISORY` in the extractor dump files.
Issue: androidx/media#1305
-----
[1]
```shell
$ AP_PADDING="DEFAULT_PAD=0" \
AtomicParsley sample.mp4 \
--artist "Test Artist" \
--album "Test Album" \
--tracknum 2/12 \
--disk 2/3 \
--year 2024 \
--genre "Gorpcore" \
--bpm 120 \
--compilation true \
--advisory clean \
--gapless true \
--sortOrder artist "Sorting Artist" \
--sortOrder album "Sorting Album" \
--preventOptimizing \
-o sample_with_metadata.mp4
```
[2]
```shell
$ AP_PADDING="DEFAULT_PAD=0" \
AtomicParsley sample.mp4 \
--genre "Metal" \
--preventOptimizing \
-o sample_with_numeric_genre.mp4
```
PiperOrigin-RevId: 628345458
Before this CL, the video sink was not reconfigured for the second video
in a sequence with video-image-video. For example, the stream offset
and listener were not set for the second video.
PiperOrigin-RevId: 628065991
Instead of initializing the video sink outside the renderer with an
empty format for composition preview, we initialize it in the renderer
with the input format for video.
PiperOrigin-RevId: 627313708
When playing a Composition, the color transfer of an image is incorrectly
passed down to be SMPTE170M, but it should be SRGB.
PiperOrigin-RevId: 626425396
For audio with more than 12 channels, no channel mask was determined, which
meant that the code to check spatializability would throw because of creating
an invalid audio format.
Return early if the channel mask was invalid instead (and assume spatialization
isn't possible).
PiperOrigin-RevId: 625618683
Before this CL, the FrameMetadataListener was set in
onReadyToInitializeCodec while it had already been set when handling
message MSG_SET_VIDEO_FRAME_METADATA_LISTENER.
PiperOrigin-RevId: 624940824
Some seek operations are currently filtered in the base classes if
the target index is not explicitly specified and the implicitly
assumed operation doesn't have an obvious target index. (Example:
calling seekToNext() at the last item in a playlist)
This is too opinionated because the actual player implementation
using this base class may be able to handle this seek request (e.g.
by adding new items on the fly or using other logic to select
the most suitable next item).
This can be solved by forwarding all seek requests to the respective
handler methods even if they are a presumed no-op. Also clarify the
Javadoc that the provided index is just an assumption if it wasn't
provided explicitly in the method call.
PiperOrigin-RevId: 624887116
Before this CL, the offset was set:
- in onPositionReset for composition preview
- in onReadyToInitializeCodec for ExoPlayer
The code flow is easier to reason about if the path for both use cases
is as shared as possible.
PiperOrigin-RevId: 624870150
This removes the TODOs without updating the links, because the
DAC-hosted images are not co-located with the hosted javadoc (unlike
when these images were referenced on exoplayer.dev before 10342507f7),
and therefore we would need to include the full path anyway, at which
point it seems clearer and more robust to keep using a fully-qualified
URL with the domain too.
PiperOrigin-RevId: 623452217
Compared to `release`, the `reset` method doesn't release the preload manager instance. This applies to the use case that an app wants to discard all the sources but keep the preload manager active for later usage.
Also rename the `releaseSourceInternal` to `removeSourceInternal`, as the latter sounds more generic for different preload manager implementations.
PiperOrigin-RevId: 623148723
In offloaded audio playback, the `DefaultAudioSink` should use the `AudioTrack.StreamEventCallback` `onPresentationEnded` to note whether the AudioTrack has completed playing all pending data.
PiperOrigin-RevId: 622885399
Both `remove(MediaItem)` and `remove(MediaSource)` return a boolean suggesting that whether the preload manager is holding the corresponding `MediaSource` and it has been removed.
PiperOrigin-RevId: 622185427
This change makes sure the `DefaultLoadControl` would work
when passed to multiple players. It makes sure and unit tests
that the loading state of a player is maintained for each player
that is using `DefaultLoadControl`.
The targetBufferSize of the `DefaultAllocator` is increased
linearly for each player and memory is allocated in a simple
first-come-first-serve manner.
PiperOrigin-RevId: 622126523
The join mode is used for two cases: surface switching and mid-playback
enabling of video.
In both cases, we want to pretend to be ready despite not having rendered
a new "first frame". So far, we also avoided force-rendering the first
frame immediately because it causes a stuttering effect for the
mid-playback enable case. The surface switch case doesn't have this
stuttering issue as the same codec is used without interruption. Not
force-rendering the frame immediately causes the first-frame rendered
callback to arrive too early though, which may lead to cases where
apps hide shutter views too quickly.
This problem can be solved by only avoiding the force-render for the
mid-playback enabling case, but not for the surface switching case.
PiperOrigin-RevId: 622105916
Also explicitly use a synchronized list to collect cues. The previous
bare `ArrayList` was probably fine, because the `ConditionVariable`
creates a memory barrier between the main thread and the test thread,
but this seems more explicit (and any performance implications of the
synchronization don't matter for this test).
PiperOrigin-RevId: 621523824
The workaround check is now part of CTS and we should be able
to rely on the PerformancePoints values (or at least can be sure
that they cover all CDD requirements)
#minor-release
PiperOrigin-RevId: 619201331
Some media can read color info values from the bitstream
and may partially set some of the SDR default values in
Format.ColorInfo. Setting these default values for SDR can
confuse some codecs and may also prevent adaptive ABR
switches if not all ColorInfo values are set in exactly the
same way.
We can avoid any influence of HDR color info handling by
disabling setting the color info MediaFormat keys for SDR
video and also avoid codec reset at format changes if both
formats are SDR with slightly different ColorInfo settings.
To identify "SDR" ColorInfo instances, we need to do some
fuzzy matching as many of the default values are assumed to
match the SDR profile even if not set.
Issue: androidx/media#1158
PiperOrigin-RevId: 617473937
Add a new method `onUsedByPlayer(PreloadMediaSource)` for `PreloadMediaSource.PreloadControl`, which will be invoked when the player starts to use the `PreloadMediaSource`, or calling `PreloadMediaSource.preload` while the player is already using that source. `DefaultPreloadManager` will immediately preload the next source when receiving `onUsedByPlayer` event.
PiperOrigin-RevId: 616789121
Confirmed that the HLG extension displays properly on Pixel 7 Pro, API 34 and Samsung S24, API 34. On these devices, this fixes the washed out HLG preview issue on API 34, where the PQ ext had a washed out look, and where the HLG ext is supported (this bug didn't occur on API 33, only 34).
More info on manual tests done to sanity-check:
* Test cases: Transformer debug SurfaceView and ExoPlayer.setVideoEffects
* Test inputs: HLG and PQ
* Test devices: Pixel 7 Pro (API 33 & 34), Samsung Galaxy S24 (API 34)
* Added debugging: Logging colorInfo used in GlUtil.createEglSurface
No regressions were seen. HLG extension is used more in API 34, and behavior stays the same on API 33. Only human-visible change without logging is that HLG content looks better on API 34, for Samsung S24 and Pixel 7 Pro.
PiperOrigin-RevId: 616131192
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.
Issue: androidx/media#1017
PiperOrigin-RevId: 614734437
This should already be the default, but some devices seem
to not adhere to this contract and assume the default is unset.
Issue: androidx/media#1169
PiperOrigin-RevId: 614697283
Some devices just don't work very well with the synchronous
model, but are currently still excluded from our approximate
API 31 check. This change allows to include additional devices
or device groups by passing in the Context to the default
adapter.
It also adopts the workaround added in ebceee08c6
for Fire TV Smart devices that exhibit this issue.
PiperOrigin-RevId: 614642545
Some FireOS6 devices ask to force the external surround global
flag and ignore any signals from the HDMI connection.
This is the equivalent change of e341944d1e
PiperOrigin-RevId: 614634499
Using the more accurate check available on later API versions
first is likely better than falling back to a fallback solution
from older API versions.
PiperOrigin-RevId: 614612628
These input types include images, video without audio, and video with audio.
While playing these inputs, the video frame presentation is always synced with
audio.
PiperOrigin-RevId: 613921719
Also remove intermediate object allocations in
`Util.toByteArray(int...)`.
`Util.toByteArray(InputStream)` is kept (but deprecated) because it's
been part of the library for a while and might be in use by some apps.
The others are much newer, so the chance of usages outside the library
is very low, so we just remove them directly.
PiperOrigin-RevId: 613878453
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.
A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.
Issue: androidx/media#1017
PiperOrigin-RevId: 613231227
The old methods are deprecated and are called from the new
method for backwards compatibility of custom implementations.
'DefaultLoadControl' is unchanged, but `ExoPlayerImplInternal`
already calls the new methods passing in the `PlayerId`,
PiperOrigin-RevId: 613197190
`BasePreloadManager` coordinates the preloading for multiple sources based on the priorities defined by their `rankingData`. Customization is possible by extending this class. Apps will implement `TargetPreloadStatusControl` to return preload manager the target preload status for a given `rankingData` of the source.
`DefaultPreloadManager` extends from the above base class and uses `PreloadMediaSource` to preload media samples of the sources into memory. It also uses an integer `rankingData` that indicates the index of an item on the UI, and the priority of the items is determined by their adjacency to the current playing item. Apps can set the index of current playing item via `DefaultPreloadManager.setCurrentPlayingIndex` when the user swiping is detected.
PiperOrigin-RevId: 612829642
This implementation generates lint errors because neither the `first`
nor `second` parameters are used, and that's generally
unexpected/incorrect for a `Comparator` implementation since it should
always consider both its parameters.
PiperOrigin-RevId: 611039632
This change aims to prioritise tracks that have a 'smooth enough for
video' frame rate, without always selecting the track with the highest
frame rate.
In particular MP4 files extracted from motion photos sometimes have two
HEVC tracks, with the higher-res one having a very low frame rate (not
intended for use in video playback). Before this change
`DefaultTrackSelector` would pick the low-fps, high-res track.
This change adds a somewhat arbitrary 10fps threshold for "smooth video
playback", meaning any tracks above this threshold are selected in
preference to tracks below it. Within the tracks above the threshold
other attributes are used to select the preferred track. We deliberately
don't pick the highest-fps track (over pixel count and bitrate), because
most users would prefer to see a 30fps 4k track over a 60fps 720p track.
This change also includes a test MP4 file, extracted from the existing
`jpeg/pixel-motion-photo-2-hevc-tracks.jpg` file by logging
`mp4StartPosition` in
[`MotionPhotoDescription.getMotionPhotoMetadata`](b930b40a16/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/MotionPhotoDescription.java (L123))
and then using `dd`:
```
mp4StartPosition=2603594
$ dd if=jpeg/pixel-motion-photo-2-hevc-tracks.jpg \
of=mp4/pixel-motion-photo-2-hevc-tracks.mp4 \
bs=1 \
skip=2603594
```
----
This solution is in addition to the `JpegMotionPhotoExtractor` change
made specifically for these two-track motion photos in
5266c71b3a.
We will keep both changes, even though that change is not strictly
needed after this one, because adding the role flags helps to
communicate more clearly the intended usage of these tracks. This
change to consider FPS seems like a generally useful improvement to
`DefaultTrackSelector`, since it seems unlikely we would prefer a 5fps
video track over a 30fps one.
Issue: androidx/media#1051
PiperOrigin-RevId: 611015459
These audio offload failure recovery tests model the DefaultAudioSink failing at audio track init and write operations in offload mode. Playback should recover and try again as DefaultAudioSink will disable offload mode.
PiperOrigin-RevId: 610372935
Some devices supporting Performance Points for decoder coverage are missing coverage over the CDD requirements for H264. For these cases ExoPlayer should fall back to legacy resolution and frame rate support checks. If there is a stream evaluated as a PerformancePointCoverageResult of COVERAGE_RESULT_NO, then ExoPlayer checks for coverage of the 720p H264 CDD requirement.
Issue: google/ExoPlayer#10898
Issue: androidx/media#693
Issue: androidx/media#966
PiperOrigin-RevId: 609740128
Even when there's no display surface, MCVR can render frames to VFP, becuase by
the time the frame is processed:
- If there's still no surface, VFP will drop the frame;
- If there's surface, the processed frame would be rendered.
In short, placeholder surface is not needed in effect enabled playback. FWIW,
it is used to swallow frames directly from MediaCodec when there's no output
surface.
PiperOrigin-RevId: 609705222
This change makes ExoPlayerImplInternal.releaseInternal() unblock the
app thread if a runtime exception is thrown while releasing components
from the playback thread.
Before this change, if a runtime exception occurred during releasing
components in the playback thread, ExoPlayer.release() would wait for
`releaseTimeoutMs` and then raise a player error. With this change,
the player error is reported only when the playback thread is blocked
but if there is a runtime exception, the application thread is
unblocked.
The impact of this change is potentially fewer ANRs on
ExoPlayer.release() at the expense of less error reporting.
PiperOrigin-RevId: 609702549
We forgot to add it when we added AudioSink.release(). The commit
includes a test that ensures ForwardingAudioSink overrides all the
methods defined in the AudioSink interface.
PiperOrigin-RevId: 609402258
If the reading period has already advanced and a track reselection procs that only affects the reading period media, then ExoPlayer may try and apply the reading period's track selection incorrectly unto the playing period. ExoPlayer should apply the playing period's track selection to the playing period instead.
PiperOrigin-RevId: 609375077
If render error occurs due to AudioTrack initialization failure in offload mode, then ExoPlayer should allow retry as subsequent attempt will be with DefaultAudioSink disabling offload.
PiperOrigin-RevId: 609304897
The `PreloadMediaPeriod.selectTracksForPreloading` can be called for multiple times at the preloading stage (before the period is being played). For example, when the period resumes preloading. This change fix the assertion failure in `ProgressiveMediaPeriod.selectTracks` caused by the wrong implementation of `PreloadMediaPeriod.selectTracksForPreloading` when it is trying to retain the previously preloaded streams.
Also the `TrackSelectorResult` parameter is changed to a list of `ExoTrackSelection`. We should compare the selections only rather than considering the `RendererConfiguration` in the `TrackSelectorResult` to decide whether to retain the streams, as for preloading case the renderers haven't consumed the samples yet.
PiperOrigin-RevId: 609126868
This change:
1. Updates the implementation of
`FrameworkMediaDrm.requiresSecureDecoder` to include the
'force allow insecure decoder' workaround logic.
2. Removes the 'force allow insecure decoder' logic from MCR
3. Removes the `requiresSecureDecoder` field from MCR (it can just
be a local derived from `codecDrmSession` now).
PiperOrigin-RevId: 607664186
Also put back a comment in DownloadTracker that is still relevant on API 19.
Also deprecate PlaceholderSurface.newInstanceV17() in favour of just
newInstance()
`Uri.appendQueryParameter` is documented to encode its arguments, so
calling `Uri.encode` beforehand results in double-encoding.
Issue: androidx/media#1075
#minor-release
PiperOrigin-RevId: 604995441
Relax the regex to only check for hyphen which is required by the specification.
Issue: androidx/media#1028
#minor-release
PiperOrigin-RevId: 604719300
These are often the same for image tracks, since we usually drop the
whole image file (both the container and actual encoded image bytes)
into a single sample, but there are cases where we emit a track with
`containerMimeType=image/jpeg` but **no** samples (from
`JpegMotionPhotoExtractor`, to carry some metadata about the image +
video byte offsets).
It's therefore more correct to implement the `supportsFormat` check
based on `sampleMimeType`, so that these 'empty' image tracks are not
considered 'supported' by `ImageRenderer`.
#minor-release
PiperOrigin-RevId: 604672331
This was already done for the TrackGroup ids in <unknown commit>,
but in some scenarios only the Format instances are known and
it's helpful to be able to identify where they came from.
Issue: androidx/media#883
#minor-release
PiperOrigin-RevId: 604644039
Add a test for this consistency in `CompositeSequenceableLoaderTest`,
and also make the
`CompositeSequenceableLoaderTest.FakeSequenceableLoader` implementation
more realistic.
#minor-release
PiperOrigin-RevId: 604604103
Transformer export and ExoPlayer previewing both read inputColorInfo from
registerInputStream now, instead of maintaining a consistent input color
throughout multiple streams in a sequence.
Therefore, we can remove inputColor-related arguments and methods now.
PiperOrigin-RevId: 603423509
If seeking between last image sample and end of the file where the current stream is not final, then EoS sample will not be provided to `ImageRenderer`. ImageRenderer must still produce the last image sample.
PiperOrigin-RevId: 603312090
This happens when using `ExoPlayer.setVideoEffects()`.
This CL also fixes the first frame not rendered problem, originally solved in
7e65cce967, but rolled back in 5056dfaa2b because the solution introduces
the flash that is observed in b/292111083.
Before media3 1.1 release, the output size of `VideoFrameProcessor` is not
reported to the app. This was changed later after introducing
`CompositingVideoSinkProvider`, where the video size after processing **is**
reported to the app. After this CL, the size is again, not reported.
PiperOrigin-RevId: 602345087
The updated algorithm has two main improvements:
- The silence padding is not constant but a ratio of the original
silence (up to a defined max) to more naturally represent the
original gaps.
- The silence is not instantly going to zero, but uses a ramp down
and up for a smooth volume transition and also retains a small
percentage of the original noise for more natural "silences" that
still contain some background noise.
#minor-release
Issue: google/ExoPlayer#7423
PiperOrigin-RevId: 602322442
The return value of onConfigure must not be ignored as it specifies
the output format of the processor, which may be different from the
input format.
#minor-release
PiperOrigin-RevId: 601799440
Many usages are needed to support other deprecations and some
can be replaced by the recommended direct alternative.
Also replace links to deprecated/redirected dev site
PiperOrigin-RevId: 601795998
It's likely that we will merge these back into their `XXXDecoder`
implementations, but this smaller change allows us to avoid including
these public symbols in the upcoming release.
#minor-release
PiperOrigin-RevId: 601432629
This method works by reflectively loading classes from the `lib-effect`
module, in order to avoid a hard dependency on this module for ExoPlayer
users that don't want video effect functionality. This change ensures
that a failure to load the necessary classes fails immediately, instead
of on a later thread inside `MediaCodecVideoRenderer` when the
reflection currently happens.
Also update the javadoc to make the dependency requirement clear.
#minor-release
PiperOrigin-RevId: 601387957
DASH: `DashMediaSource.Factory` would only propagate it to `DashChunkSource.Factory` -> `BundledChunkExtractor.Factory`
SS: `SSMediaSource.Factory` -> `SsChunkSource.Factory`
HLS: `HlsMediaSource.Factory` -> `HlsExtractorFactory`
Remove nullability of SubtitleParser.Factory across the stack
#minor-release
PiperOrigin-RevId: 601250013
The `SubtitleParser.Factory` is no longer @Nullable and the experimenting toggle is used to enable/disable the use of this factory for subtitle parsing during extraction.
The three places that will hold the "truth" for the `SubtitleParser.Factory` are: BundledChunkExtractor.Factory, SsChunkSource.Factory, DefaultHlsExtractorFactory
DASH: `DashMediaSource.Factory` would only propagate it to `DashChunkSource.Factory` -> `BundledChunkExtractor.Factory`
SS: `SSMediaSource.Factory` -> `SsChunkSource.Factory`
HLS: `HlsMediaSource.Factory` -> `HlsExtractorFactory`
#minor-release
PiperOrigin-RevId: 601151615
Those classes only needed to have access to a `SubtitleParser.Factory` to get a potentially updated `Format` for TrackGroups. The `SubtitleParser.Factory` was only used to check the support for the `mimeType` and getting some cue-related behaviour.
This introduced complexity in a way that both Periods and Extractors needed to have the same `SubtitleParser.Factory` in their individual stacks. To ensure that the sample queue would get the same transcoded/original format.
Instead, now we expose `getOutputTextFormat` methods on `ChunkExtractor.Factory`, `SsChunkSource.Factory` and `HlsExtractorFactory`. Those are the dependencies that Hls/Ss/DashMediaPeriod can make use of to delegate the format-updating logic to.
#minor-release
PiperOrigin-RevId: 601130714
These symbols in `lib-effect` are referenced via reflection from
`CompositingVideoSinkProvider` in `lib-exoplayer` in order to avoid
a hard dependency from `lib-exoplayer` to `lib-effect`. Without this
keep rule, the symbols can get renamed by R8 resulting in the
invocations failing.
#minor-release
PiperOrigin-RevId: 601074636
We keep the previous parsing-during-rendering tests, even though they
can be a bit flaky, because this is an important regression test. The
regression risk is lower for this instrumentation test compared to
robolectric tests with different `ShadowLooper` behaviour.
#minor-release
PiperOrigin-RevId: 600781035