The `bear-cbr-no-seek-table-trailing-garbage.mp3` test file was generated by appending 150kB of `0xDEADBEEF` onto the end of `bear-cbr-variable-frame-size-no-seek-table.mp3`.
Issue: androidx/media#1563
#cherrypick
PiperOrigin-RevId: 670131828
This interface was used by Boxes.moov. This CL removes the interface and just uses the Track object directly.
Since Track is package-private it seems fine to use it directly.
The drawback with interface is that, with every new field addition in the
Track class, we need to update the interface as well (if we need to access that field for moov box).
PiperOrigin-RevId: 669295399
Adds a class that represents an image rectangle
in OpenGL coordinate convention.
android.graphics.Rect puts (0, 0) as the top-left corner:
it enforces `Rect.top <= Rect.bottom` and this matches
`android.graphics.Bitmap` coordinates: docs https://developer.android.com/reference/android/graphics/Rect
This is different from OpenGL coordinates where (0, 0) is
at the bottom-left corner. I.e. GlRect.bottom <= GlRect.top: docs https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glReadPixels.xhtml
The reason for this change is to allow a public API GlRect
getScaledRegion() which selects a region of pixels of a GL texture
to be copied to CPU memory.
PiperOrigin-RevId: 669231826
The CL aims to
1. Shorten unnecessary lengthy chatty comments.
2. Remove dead TODOs.
3. nit fixes for comment style consistency.
4. Remove usage of "we" in the comments.
5. Media3 muxer does not need to mention the behaviour of framework muxer
unless its required for some purpose, so remove them.
PiperOrigin-RevId: 668985875
The existing logic was not working sometimes because:
1. The repeated scheduling in releaseAllFramesFromMediaCodec was
starving the thread on which the SurfaceTexture frameAvailableListener
was called.
2. The case where a pending frame arrives on the surface after flush
finishes executing was not handled.
The consequence of both problems is that availableFrameCount ended up
being > pendingFrames.size().
PiperOrigin-RevId: 668916256
These tests do not test performance. Moving them out of this directory
ensures they are run on emulators and on more than 1 physical device.
PiperOrigin-RevId: 668859017
DASH periods don't have to start at the beginning of a segment. In
these cases, they should report an initial discontinuity to let the
player know it needs to expect preroll data (e.g. to flush renderers)
This information is only available in the ChunkSampleStream after
loading the initialization data, so we need to check the sample
streams and tell them to only report discontinuities at the very
beginning of playback. All other position resets are triggered by
the player itself and don't need this method.
Issue: androidx/media#1440
PiperOrigin-RevId: 668831563
In the flaky test `ExoPlayerTest.loading_withLargeAllocationCausingOom_playsRemainingMediaAndThenThrows`, it is indeterministic that when the message `MSG_IO_EXCEPTION` from the loader thread will arrive on the playback looper. If it arrives after `MSG_PERIOD_PREPARED`, then the period can continue loading and get the three samples written to the `SampleQueue` before the intentional OOM surfacing to the `ExoPlayerImplInternal`, otherwise, the OOM will be detected by `ExoPlayerImplInternal` very early and the player disallows to load three samples, which will cause the assertion to fail.
As we are expecting the three samples to play until the playback fails, we should assume that the `Loader` encounters the OOM after those samples loaded, thus we need to put this trigger a bit later until the `SampleStreamItem`s are handled by the `FakeSampleStream`. This could be checked by the return value of `FakeMediaPeriod.continueLoading` (super class implementation). However, `FakeMediaPeriod.continueLoading` originally always returns `true`, which is not aligned with the javadoc of `MediaPeriod.continueLoading`:
"return `true` if progress was made, meaning that `getNextLoadPositionUs()` will return a different value than prior to the call, `false` otherwise."
then we should also modify that logic.
PiperOrigin-RevId: 668438316
This callback allows listeners to track when individual renderers
allow or prevent playback from being ready. For example, this is useful
to figure out which renderer blocked the playback the longest.
PiperOrigin-RevId: 667970933
Before this CL, the video sink was stuck if a flush was executed:
- after VideoSink.onInputStreamChanged, which is setting
pendingInputStreamBufferPresentationTimeUs and
- before the previous stream was fully rendered.
This is because pendingInputStreamBufferPresentationTimeUs was not reset
to TIME_UNSET when flushing the sink, so that the sink was still waiting
for the last frame of the previous stream to be rendered in
handleInputFrame/Bitmap.
PiperOrigin-RevId: 667924517
OpenGL ES 3.0 likely can be used since Android 18.
Moving to a higher version context more often can make
sharing GL context easier for apps
PiperOrigin-RevId: 667915331
* Changes to GlUtil to manage Pixel Buffer Objects and asynchronous
GPU -> CPU glReadPixels
* Make ByteBufferConcurrentEffect non-blocking
PiperOrigin-RevId: 667908805
* new ByteBufferGlEffect GlEffect that enables API users to
implement an effect that accesses video frame data via CPU-mapped ByteBuffer
* ByteBufferConcurrentEffect responsible for reading
video frame data in CPU-accessible ByteBuffer
PiperOrigin-RevId: 666375594
Implement a QueuingGlShaderProgram which queues up OpenGL frames and allows
asynchronous execution of effects that operate on video frames without a
performance penalty.
PiperOrigin-RevId: 666326611
The logic was assuming that the shader program was only flushed when
seeking. This is true if a single renderer is used but, with multiple
renderers, the shader program can be flushed at the transition.
This change is necessary to make the test pass for prewarming because 2
video renderers will be used in that case.
PiperOrigin-RevId: 666215967
Per the javadoc, the method `MediaPeriod.maybeThrowPrepareError` is only allowed to be called before the period has completed preparation. For later errors in loading the streams, `SampleStream.maybeThrowError` will be called instead.
PiperOrigin-RevId: 665831430
It is possible for playback to be stuck when there is failure in loading further data, while the player is required to load more due to the buffered duration being under `DefaultLoadControl.bufferForPlayback`. Therefore, we check if there is any loading error in `isLoadingPossible`, so that the player will allow the playback of the existing data rather than waiting forever for the data that can never be loaded.
Issue: androidx/media#1571
#cherrypick
PiperOrigin-RevId: 665801674
This allows seek operations in files that were previously unseekable, particularly those with variable bitrate (VBR) or constant bitrate (CBR) with silence frames.
New samples for tests were created by adding silence frames to existing narrowband and wideband versions.
PiperOrigin-RevId: 665349241
The CL adds another way of writing editable video
tracks where the samples will be interleaved with the
primary track samples in the "mdat" box.
PiperOrigin-RevId: 665313751
This uses a 'bundled' extractor (`SubtitleExtractor`) because
`MediaParser` doesn't support transcoding subtitles to
`application/x-media3-cues`. This transcoding is required to support
non-legacy subtitle handling where they are parsed during extraction,
instead of during rendering.
PiperOrigin-RevId: 665282298
In order to support building with `gradle` a new `build.gradle` file was added together with `Android.mk`, `Application.mk`, and `libiamf.mk` necessary for local builds with NDK.
After this change, IAMF files may also be played in the ExoPlayer demo built locally (without blaze).
PiperOrigin-RevId: 664841684
This is only used as part of legacy subtitle decoding. If any apps are
using it directly (rather than via `DashMediaSource` or `SsMediaSource`)
they probably need to enable legacy decoding in `TextRenderer` to avoid
playback failures.
PiperOrigin-RevId: 663740343
The method currently has two ways of operating with a complicated
contract:
1. outputBuffer == null -> sets a new outputBuffer and starts
draining it as far as possible.
2. outputBuffer != null -> continues draining a previous buffer,
requires that the input parameter is the same as outputBuffer.
This contract can be made cleaner by splitting the logic into
(1) setting a new output buffer and (2) draining the output buffer.
Only one parameter is needed for each method and there is no
requirement to pass in the same argument as before because we already
know what we are draining. This also means the caller of the method
doesn't have to keep track of the actual outputBuffer, allowing
further processing steps in the future that change the drained
instance.
PiperOrigin-RevId: 663316251
This makes it clearer that the part inside and outside the parentheses
are clearly different, and not "just" a reference to `Player.Events`.
Specifically this syntax is showing that the function has a `Player`
"receiver", **and** is a function from `Player.Events` to `Unit`.
https://kotlinlang.org/docs/lambdas.html#function-types
PiperOrigin-RevId: 663293405
This makes the class available to custom MP4-parsing implementations,
while also allowing it to be used by `muxer` in future.
'Box' is the term used throughout the ISO 14496-12 spec, while the
'Atom' nomenclature was used in an earlier form of the spec
(Quicktime).
This change moves it from `extractor.mp4.Atom` to `container.Mp4Box`,
to be consistent with existing MP4-specific types in the `container`
module like `Mp4TimestampData`.
PiperOrigin-RevId: 663274752
The audio mixing is not deterministic on real device testing because of
threading, but runs deterministically on robolectric tests
PiperOrigin-RevId: 662925912
Use ExoPlayer dynamic scheduling to reduce the render() interval for
older API devices where `DefaultCodec.getMaxPendingFrameCount()` is set
to 1 in order to prevent frame drops.
Controlled via API on DefaultDecoderFactory.
Add TransformerForegroundSpeedTest that mimics transcoding while the app
is in foreground.
PiperOrigin-RevId: 662925764
The parameter class will allow addition of more
parameters (link shouldInterleaveSamples), which are specific to
editable video file format.
PiperOrigin-RevId: 662923844
AMR samples with identical data but different names, previously used to generate uniquely named dump files, have been deleted. Instead, `AssertionConfig` is now used to set the dump file prefix, ensuring files are generated with unique names.
PiperOrigin-RevId: 662883541
Previous to this change, `FrameworkMediaDrm.requiresSecureDecoder`
ignores its `sessionId` parameter on API 31+, and uses only the
`mimeType` parameter. This means the result [assumes the session is
opened at the 'default security
level'](https://developer.android.com/reference/android/media/MediaDrm#requiresSecureDecoder(java.lang.String)):
> The default security level is defined as the highest security level
> supported on the device.
This change is a no-op in all (?) cases, because the `ExoMediaDrm`
interface only exposes the zero-arg `openSession()` method, which in the
framework case **also** assumes the highest security level is preferred:
> By default, sessions are opened at the native security level of the
> device.
However, it seems more obviously correct to only make this
"highest/native security level" assumption in one place
(`openSession()`), and check the session's **actual** security level
everywhere else.
Issue: androidx/media#1603
PiperOrigin-RevId: 662872860
Constant bit rate (CBR) seeking can be enabled even when the length of the file is not known.
Additionally, dump files for these files have been updated to accurately log the `position` when `timeUs` is set to `0`.
PiperOrigin-RevId: 662868607
This method was added in API 31 (S) but it's non-functional
(incorrectly, silently, returns `false`) on the Widevine plugin version
(`16.0`) from R (API 30), which some devices up to at least API 34 are
still using.
This results in ExoPlayer incorrectly selecting an insecure decoder for
L1 secure content, and subsequently calling
`MediaCodec.queueInputBuffer` instead of `queueSecureInputBuffer`,
which is not supported and generates the following error:
> Operation not supported in this configuration: ERROR_DRM_CANNOT_HANDLE
Issue: androidx/media#1603
#cherrypick
PiperOrigin-RevId: 662852176
The TrackToken is primarily for public API.
Using Track object internally will remove unnecessary
type casting at various places.
PiperOrigin-RevId: 662564224
When there is an exception thrown from the `LoadTask`, the `Loader` will call `Loader.Callback.onLoadError`. Some implementations of `onLoadError` method may call `MediaPeriod.onContinueLoadingRequested`, and in the `PreloadMediaSource`, its `PreloadMediaPeriodCallback` will be triggered and then it can further call `continueLoading` if it finds needed. However the above process is currently done synchronously, which will cause problem. By calling `continueLoading`, the `Loader` is set with a `currentTask`, and when that long sync logic in `Loader.Callback.onLoadError` ends, the `Loader` will immediately retry, and then a non-null `currentTask` will cause the `IllegalStateException`.
Issue: androidx/media#1568
#cherrypick
PiperOrigin-RevId: 662550622
Moving this field to `IamfDecoder` instead of `iamf_jni` allows multiple instances of the IAMF decoder with possibly different configurations at the same time.
PiperOrigin-RevId: 662548068
Check if the output device supports spatialization for the requested output format. If so, return a stream decoded for 6 channels in a 5.1 layout. Otherwise, return a stream decoded for 2 channels in a binaural layout.
PiperOrigin-RevId: 662546818
This is groundwork to moving `Atom` to the `container` library, which
we want to do before making it public (so it can be used by `muxer` in
future).
PiperOrigin-RevId: 662453520
After this change, a WakeLock of PowerManager#PARTIAL_WAKE_LOCK level would be acquired when the media is paused due to playback attempt without suitable output.
This WakeLock will be release either when the suitable media output has been connected or the set timeout to do so has expired.
PiperOrigin-RevId: 661570346
This is an additional signal that legacy subtitle support needs to be
explicitly enabled, and is going away at some point.
PiperOrigin-RevId: 661305694
If the length of the `ExtractorInput` is not known then the
`subtitleData` field is re-sized by 1kB each time
(`SubtitleExtractor.DEFAULT_BUFFER_SIZE`), so the end of the array is
often not populated. This change ensures that `length` is propagated to
`SubtitleParser`, so that implementations don't try and parse the
garbage/zero bytes at the end of the array.
Discovered while investigating Issue: androidx/media#1516
#cherrypick
PiperOrigin-RevId: 661195634
Some RTSP servers may provide media descriptions for custom streams that are not supported. ExoPlayer should skip the invalid media description and continues parsing the following media descriptions.
To start, ExoPlayer will still error on malformed SDP lines for media descriptions, but will now skip media descriptions with "non-parsable" formats as described by [RFC 8866 Section 5.14](https://datatracker.ietf.org/doc/html/rfc8866#section-5.14).
Issue: androidx/media#1472
PiperOrigin-RevId: 660826116
App users can choose arbitrary data that might not be
anticipated by developers. Transformer shouldn't `checkState` based on
media data or file type -- report an error for unsupported data instead.
Public API change `ImageAssetLoader` needs to parse MIME type and now accepts
`Context` as parameter.
PiperOrigin-RevId: 660762459
This is caused when the requested "output start time" is equal to or
larger than the last event time in a `Subtitle` object.
This resolves the error in Issue: androidx/media#1516, but subtitles are still not
renderered (probably because the timestamps aren't what we expect
somewhere, but I need to investigate this part further).
#cherrypick
PiperOrigin-RevId: 660462720
Previously in MultiInputVideoGraph, each VFP would destroy the shared
eglContext, such that the same eglContext object is destroyed multiple times.
Adding a flag to disallow this.
The alternative being we could add a flag on the VFP constructor, but I think
that is too subscriptive (meaning if we later might want to add another boolean
to control another GL behaviour, multiple booleans would make the class less
reason-able), and would incur a lot of code changes at places.
PiperOrigin-RevId: 660354367
The method is not supposed to work with any input byte[]
so its best to make it non static and add appropriate validations.
PiperOrigin-RevId: 659906543
The integration with external libraries like Glide or Coil is
currently extremely complicated. Providing the boilerplate code
to handle the ImageDecoder interface and a better hook for custom
image decoders in DefaultRenderersFactory allows apps to easily
inject their own logic for external image loading libraries.
PiperOrigin-RevId: 659508914
There are two ways to write editable tracks samples.
1. In the embedded edit data MP4.
2. Interleaved with primary tracks samples.
Initial plan was to support only option 1 but then the
decision is to support both ways. To identify between these two
an additional key will be required.
Option 2 is yet to be implemented in Mp4Muxer.
PiperOrigin-RevId: 658791214
This API allows users to retrieve the sample size, ensuring they can allocate sufficient buffer capacity before utilizing the `readSampleData(ByteBuffer buffer, int offset)` method to read data.
PiperOrigin-RevId: 658772408
Instead of hard-coding values in multiple files, all default values are declared in `IamfDecoder`. Additionally, the max number of frames used for output buffer initialisation is fetched from `libiamf` native functions.
PiperOrigin-RevId: 658772175
For now, the only extension function on the `Player` has been used in a Compose demo. It can be promoted to a proper module where in the future other extension functions will reside. Given that `Player` is in `androidx.media3.common`, the corresponding KTX library for it is `androidx.media3.common-ktx`
To start using the new `suspend fun listen`, one must add `androidx.media3:media3-common-ktx` as a Gradle dependency and `import androidx.media3.common.listen`
PiperOrigin-RevId: 658771029
This is needed to correctly handle files with trailing non-MP3 data
(which is indicated by the length in the `Info` frame being shorter than
the overall length of the file).
The test file was generated by appending 150kB of `DEADBEEF` onto the
end of `test-cbr-info-header.mp3`, and the test asserts that the
extracted samples are identical.
Issue: androidx/media#1480
#cherrypick
PiperOrigin-RevId: 658727595
It will be used for Kotlin-specific functionality like extension functions on the classes from the `media3-common` module. To import it, add the following to your build.gradle file:
`implementation("androidx.media3:media3-common-ktx:1.X.Y")`
PiperOrigin-RevId: 658492256
The data source may behave differently, depending on the provider,
so we can extend the contract test to check all available providers.
PiperOrigin-RevId: 658457650
Package-private until API is more useable.
Similar to frame analyzer mode: uses ImageReader instead of an encoder,
and no muxer.
PiperOrigin-RevId: 658446675
Transformer.experimentalSetMaxFramesInEncoder controls max number
of frames in encoder.
VideoFrameProcessor now allows delayed releasing of frames to Surface,
while still using the original presentation time.
VideoSampleExporter can now configure video graphs to not render frames
automatically to output surface.
VideoSampleExporter.VideoGraphWrapper tracks how many frames are ready
to be rendered to Surface, and how many frames are already in-use by encoder.
PiperOrigin-RevId: 658429969
Add parameterized test for codecs supported by InAppMuxer.
Split TransformerWithInAppMuxerEndToEndParameterizedTest tests
between parameterized and non parameterized
This will be helpful for adding more tests which need not to
be parameterized.
PiperOrigin-RevId: 658353532
Refactor to replace instances of `RuntimeException` with `IllegalStateException`.
This change ensures exceptions can be handled more specifically without
unintended catches of unrelated exceptions.
PiperOrigin-RevId: 658337459
For some predefined keys the type of value is already defined.
Early validation will help avoiding error when processing this data later.
PiperOrigin-RevId: 658060844
Added a new data source which acts an adapter to read media data from platform `MediaDataSource`. This enables adding the `setDataSource(MediaDataSource)` API to `MediaExtractorCompat`.
PiperOrigin-RevId: 657564901
Added three `setDataSource` APIs in `MediaExtractorCompat`:
- `setDataSource(Context context, Uri uri, @Nullable Map<String, String> headers)` to set data source with a content URI and optional headers.
- `setDataSource(String path)` to set data source using a file path or HTTP URL.
- `setDataSource(String path, @Nullable Map<String, String> headers)` to set data source using a file path or HTTP URL with optional headers.
PiperOrigin-RevId: 657563973
- Modified the logic of `open()` and `read()` methods to handle scenarios where length is unset for the `FileDescriptor` provided.
- Added unit test and contract test to handle this case.
Also used `getDeclaredLength()` instead of `getLength()` to set the length of `AssetFileDescriptor` in unit tests and contract tests.
PiperOrigin-RevId: 657551343
These tests addresses two identified gaps in the contract:
- Ensures that the output buffer offset passed to the `DataSource.read` method is correctly applied.
- Verifies that the position within the input stream is properly incremented when reading in two parts.
PiperOrigin-RevId: 656358935
Public methods either assert they're running GL thread, or
submit a task to run on GL thread.
Move methods to keep interface implementations together.
Add javadoc to VideoFrameProcessingTaskExecutor to clarify which
thread can call each public method.
PiperOrigin-RevId: 655978796
The builtin speaker is to be supported as a suitable output when that is deliberately selected for the media playback by the user in Wear OS.
PiperOrigin-RevId: 655950824
The DefaultPreloadManagerTest didn't to catch this because we use main looper as the preload looper in the tests. This CL also improves the tests by assigning the preload looper with one that corresponds to a different thread.
PiperOrigin-RevId: 655664189
The dependency on the native `opusV2JNI` library doesn't work from
Robolectric, so the `assumeTrue` statements in this test always fail,
and the tests are always skipped. Moving it to an instrumentation test
allows the native library to be successfully loaded, and the test to be
run.
PiperOrigin-RevId: 655570129
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
Build upon Transformer.videoFrameProcessorFactory in MultipleInputVideoGraph
Check that Transformer.videoFrameProcessorFactory is DefaultVideoFrameProcessor
for multi-input video
Fixes https://github.com/androidx/media/issues/1509
PiperOrigin-RevId: 655232381
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
eglDestroySurface only destroys the surface when it's made not current.
Pass the placeholder surface in FinalShaderProgramWrapper and use it
when destroying eglSurface.
PiperOrigin-RevId: 655139661
Add VideoFrameProcessingTaskExecutor.invoke() method that blocks until
Task has executed on GL thread.
Use that for FinalShaderProgramWrapper.setOutputSurfaceInfo
PiperOrigin-RevId: 655119768
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
This was used in media1 `MediaItemDescription` to indicate the download
status of a media item. When connected to a legacy
`MediaBrowserServiceCompat` the Media3 browsers converts the legacy
media item to a Media3 `MediaItem` and converts the extras of
`MediaDescriptionCompat.extras` to `MediaMetadata.extras`.
#cherrypick
PiperOrigin-RevId: 654625502
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
All methods check if the player is currently handling the ad source
by calling isCurrentAdPlaying(). This method was missing a check
for empty timelines that throws an exception when trying to access
a non-existent period.
Also add this check to two methods that assume the current item
is the ads source, but didn't check it yet.
PiperOrigin-RevId: 653963557
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
Creating a moov box is same as creating any other box so
there is no particular need to have a separate class for this.
In a follow up CL the method will be moved into Boxes.java along with
other box creation methods.
Made nit changes in the final fields ordering to match with
constructor parameter ordering.
PiperOrigin-RevId: 653602558
This test is flaky at p4head, because CompositionPlayer has no logic to
ensure a specific input is used to configure the audio graph. Depending
on which sequence registers input first, it changes the output format
of the media.
By setting effects on the 2nd sequence, both inputs are the same format
and this flakiness is avoided in the test.
PiperOrigin-RevId: 653582441
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
Boxes.moov() simply wraps the subboxes and this logic can be
put into main method which has all the logic of creating moov box.
This is to eventually move Mp4MoovStucture.moov() into
Boxes.java where all other box creation methods are already present.
PiperOrigin-RevId: 653319292
-----
Context:
* Each sequence is wrapped as a single MediaSource, each being played
by an underlying ExoPlayer.
* Repeat mode is typically implemented in Players as a seek to the next
item in the playlist.
-----
This CL:
Repeat mode is triggered by listening for when the main input player
sees a play when ready change due to the end of the media item.
There is a slight delay at the end of the playback, before it repeats.
Setting repeat mode on the underlying players addresses this, but means
that the players will seek without waiting for the CompositionPlayer,
and as such previewAudioPipeline does not get the correct signals
around blocking/flushing.
PreviewAudioPipeline - The seek position can validly be C.TIME_UNSET,
however preview pipeline did not handle this case.
CompositionPlayer getContentPosition is given (through a lambda) as a
supplier to the State object, which means any comparisons between
previous/new state for this value does not work. In SimpleBasePlayer,
there is logic to use the positionDiscontinuityPositionUs for the
position change (see getPositionInfo called from
updateStateAndInformListeners), however this logic is not considered in
getMediaItemTransitionReason, so a condition needed to be added for
this case.
-----
Tests:
* Dump files clearly show the position and data is repeated.
* Assertions on the reasons for transitions or position
discontinuities.
PiperOrigin-RevId: 653210278
Also resolve some failures.
Lint checks [aren't enabled in tests by default](http://groups.google.com/g/lint-dev/c/rtjVpqHmY0Y).
This change suppresses `NewApi` failures in Robolectric tests because
these tests only run at 'target SDK' by default (currently 30), but the
lint doesn't understand this and so flags spurious issues with API
usages below this.
PiperOrigin-RevId: 653172059
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
When removing one listener from the `ListenerSet`, we release the corresponding `ListenerHolder`, which prevents the event queued or sent later than the removal from being invoked. We should also do this in the method `ListenerSet.clear()` where every listener is removed.
PiperOrigin-RevId: 652535216
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
Sources (for example media projection) can populate the `Surface` from
`SurfaceAssetLoader` with timestamps that don't start from zero. But
`MuxerWrapper` assumes the latest sample timestamp can be used as the duration
when it calculates average bitrate and notifies its listener.
This can cause a crash because the calculated average bitrate can be zero if
the denominator duration is large enough.
Use the max minus first sample timestamp across tracks instead to get the
duration.
Side note: the large timestamps from the surface texture when using media
projection arrive unchanged (apart from conversion from ns to us) in effect
implementations and in the muxer wrapper (and are passed to the underlying
muxer). The outputs of media3 muxer and the framework muxer are similar.
PiperOrigin-RevId: 652422674
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
Also promote all H.265 constants to be public in `NalUnitUtil` with
`H265_` prefixes, for consistency.
A lot of these names are used in h.265 too (and `NalUnitUtil` handles
both), but with different values, so this rename aims to avoid
accidentally using an h.264 value in an h.265 context.
PiperOrigin-RevId: 651774188
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
This is because the force EOS workaround for videos is longer than the original
muxer timeout. This way the apps depending on Transformer won't have to manually
set the muxer timeout on emulators.
PiperOrigin-RevId: 651355755
The integration with `SubtitleTranscodingExtractorOutput` has been
moved inside the relevant `Extractor` implementations instead.
PiperOrigin-RevId: 651213564
When testing locally it seemed that upgrading KGP to `1.9.20` resolved
this, but testing again confirms this was incorrect, so the problem
was reintroduced in 00d1e70a34.
This change reverts back to KGP `1.9.0` (since upgrading didn't help)
and instead implements the workaround suggested in
https://issuetracker.google.com/278545487. The workaround is now in
the `lib-common` `build.gradle` file, which is transitively depended
on by all modules (and therefore all apps that use this library), so
there's no need for any developer action, and so the release note is
removed.
Issue: androidx/media#1262
PiperOrigin-RevId: 651066418
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
As reported in Issue: androidx/media#1493 we already use `HEADSETHOOK` to start
waiting for a double-tap, but we don't consider it for the second tap.
Similarly, we previously considered `PLAY` for the second tap, but not the first.
Only `HEADSETHOOK` and `PLAY_PAUSE` are
[documented](https://developer.android.com/reference/androidx/media3/session/MediaSession#media-key-events-mapping)
to transform double-tap to `seekToNext`. So this change removes the
`PLAY` detection from the second tap.
#cherrypick
PiperOrigin-RevId: 651017522
Stereo view information is stored in the 3D reference displays information SEI and the optional vexu box. Parsing of the SEI and vexu box is added, and based on the parsed info, proper mapping of primary/secondary view to left/right eye is determined.
PiperOrigin-RevId: 651002190
Add support for MPEG4 codec to enable muxing video encoded with the mp4v-es codec. Use esdsBox method to generate esds box required for Mp4v box.
PiperOrigin-RevId: 651000744
Some external media files have CodecSpecificData greater than 128 bytes. Currently, that size
isn't fitting in one byte. Hence, added support to store large CodecSpecificDataSize, as per
ISO standard, by extending to more than one byte as required.
PiperOrigin-RevId: 650972472
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
Changes to FragmentedMp4Extractor to parse additional sample dependency
information and mark output samples as "no other samples depend on this".
Only applies to H.264 tracks.
Controlled by new fMP4 flag: FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES
PiperOrigin-RevId: 650538377
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
Leb128 is a little-endian long of variable byte length. The format is used during the extraction of the size of the OBU configuration for the iacb configuration box.
PiperOrigin-RevId: 650295002
Once a service is started as a foreground service, it must
be started into the foreground. This means an app can not
suppress a play command arriving from the `MediaButtonReceiver`
once the receiver has started the service.
This change adds a method to the `MediaButtonReceiver` that
allows app to suppress starting the service to not get into
this situation of wanting to suppress the play command after
the service is already started.
Issue: androidx/media#1528
PiperOrigin-RevId: 650280025
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
This utility helps apps to forward to another Player while overriding
selected behavior or state values. The advantage to a ForwardingPlayer
is that the SimpleBasePlayer base class keeps ensuring correctness,
listener handling etc.
The default forwarding logic tries to stay as close as possible to the
original method calls, even if not strictly required by the Player
interface (e.g. calling single item addMediaItem instead of
addMediaItems if only one item is added).
Issue: androidx/media#1183
PiperOrigin-RevId: 650155924
Since the muxer supported only AAC audio codec, the esdsBox was unconditionally created within the audioSampleEntry. This CL refactors the box creation logic by moving it to the codecSpecificBox method. This is to make adding support for new audio codecs easier.
PiperOrigin-RevId: 650130935
The Timeline, Tracks and MediaMetadata are currently provided
with a list of MediaItemData objects, that are a declarative
version of these classes. This works well for cases where
SimpleBasePlayer is used for external systems or custom players
that don't have a Timeline object available already. However,
this makes it really hard to provide the data if the app already
has a Timeline, currently requiring to convert it back and forth
to a list of MediaItemData.
This change adds an override for `State.Builder.setPlaylist`
that allows to set these 3 objects directly without going
through MediaItemData. The conversion only happens when needed
(e.g. when modifying the playlist).
PiperOrigin-RevId: 649667983
The value is basically a duplicate of the information stored
in the timeline field. Reducing the source of truth to the
single Timeline also allows acceptance of other Timelines in the
future that don't necessarily have the helper structure of
the playlist.
To allow apps to retrieve the current playlist as it is, we
add a getter instead.
PiperOrigin-RevId: 649667281
Changes to Mp4Extractor to parse additional sample dependency information
and mark output samples as "no other sample depend on this".
Only applies to H.264 tracks.
Controlled by new mp4 flag: FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES
PiperOrigin-RevId: 649640184
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
This is a new `DataSource` that can be used to read from a `FileDescriptor`.
Limitations:
- The provided file descriptor must be seekable via lseek.
- There's no way to duplicate a file descriptor with an independent position (it
would be necessary instead for the app to provide a new FD). Therefore this
implementation will only work if there's one open data source for a given file
descriptor at a time.
PiperOrigin-RevId: 649443584
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
Hardware decoder on some devices fails to write 1920x1080 YUV_420_888 buffers into an ImageReader. This change allows us to remove skipCalculateSsim device workaround in ExportTest.java.
VideoDecodingWrapper now uses media3.MediaExtractorCompat: necessary for parsing of MediaFormat#KEY_CODECS_STRING and decoder capabilities check
PiperOrigin-RevId: 648726721
Lint somehow complains that the integer resulting from the bit-manipulation shouldn't be passed as an @IntDef parameter.
#cherrypick
PiperOrigin-RevId: 648687698
Deprecate `setInputDefaultBufferSize` and `setRequireRegisteringAllInputFrames`
as the new input stream type replaces these (as far as we know they are always
used together).
This is in preparation for supporting asset loaders signaling that they require
these features, specifically for recording from a surface.
PiperOrigin-RevId: 648686087
This is required before we can move CEA-6/708 parsing from the rendering
side of the sample queue to the extraction side.
This re-ordering is needed for video encodings with different decoder
and presentation orders, because the CEA-6/708 data is attached to each
frame and needs to be processed in presentation order instead of decode
order. This change re-orders frames within a group-of-pictures, but also
takes advantage of `maxNumReorderFrames/Pics` values to cap the size of
the re-ordering queue, allowing caption data to be released 'earlier'
than the end of a GoP.
Annex D of the CEA-708 spec (which also applies for CEA-608 embedded in
SEI messages), makes the need to re-order from decode to presentation
order clear.
PiperOrigin-RevId: 648648002
This change extends the error replication to a given set of
error codes (not only authentication error), but only
replicates an error if the caller of the service `Callback`
is a legacy controller. It also makes error replication
configurable so that apps can opt-out and report errors
manually instead, or define the error codes for which
replication is enabled.
The change also removes the restriction of `sendError` only
being available for Media3 controllers. Instead, sending an
error to a legacy controller updates the platform playback
state in the same way as sending the error to the media
notification controller.
#cherrypick
PiperOrigin-RevId: 648399237
Add the following NAL unit parsing utility functions that will be needed for the MV-HEVC support as proposed in Apple's HEVC stereo video interoperability profile:
- NAL unit header parsing to get the layer information needed for MV-HEVC support.
- VPS parsing, including vps_extension() needed for MV-HEVC support.
- SPS parsing modifications to support MV-HEVC.
PiperOrigin-RevId: 647329211
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.
Previously we assumed that `surfaceSyncGroupV34` was always non-null on
API 34, but this isn't true in edit mode. Instead we add an explicit
null-check before accessing it. We don't need to null-check it at the
other usage site because we are already null-checking `surfaceView` (via
`instanceof` check).
Issue: androidx/media#1237
#cherrypick
PiperOrigin-RevId: 645008049
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
This workaround is only applied on API 34, because the problem isn't
present on API 33 and it is fixed in the platform for API 35 onwards.
Issue: androidx/media#1237
#cherrypick
PiperOrigin-RevId: 644729909
In the case of a legacy session app providing an error
code different to `ERROR_UNKNOWN` without an error
message, a localized fallback message is provided
instead of ignoring the error.
#cherrypick
PiperOrigin-RevId: 644704680
The Javadoc was indicating that the duration should always be set,
but it doesn't need to be set in most cases for export.
PiperOrigin-RevId: 644685827
Includes adjusting how effects are defined, to make it clearer in a
test that a given ItemConfig has effects associated with it.
PiperOrigin-RevId: 644684308
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
These calls have no effect because the VideoFrameReleaseControl of
CompositionPlayer is created with allowedJoiningTimeMs set to 0.
PiperOrigin-RevId: 644274524
This is an internal refactor with no logic changed.
There is a duplication in information and a lack of consistency around
the use of test assets in transformer androidTest. This change
refactors each asset to be defined as its own AssetInfo, with the other
relevant parts stored alongside the uri.
Once this is in place, we can consider other useful functionality, such
as having boolean flags for what tracks an asset has, helper methods
for whether an asset is local or remote, and more. This will reduce the
manual overhead necessary to use more assets in tests, and in
particular leads towards easily using new & existing assets in
parameterized tests.
PiperOrigin-RevId: 644040595
This is done by reserving some space for moov box at the start of the file and writing it there if it fits. If it doesn't fit, then it is written at the end of the file.
PiperOrigin-RevId: 643944698
This method allows customizing the maximum position when using `Player.seekToPrevious()`.
This commit also adds two new methods to `TestExoPlayerBuilder`:
- `setMaxSeekToPreviousPosition(long)`
- `getMaxSeekToPreviousPosition()`
Images are rendered into an ImageView (on top of the video shutter).
The image view is set to the images emitted by ExoPlayer's ImageOutput
and cleared when there is no longer a selected image track.
In order to keep the existing behavior of video tracks to only clear
the old output once the new first frame is rendered (avoiding short
periods of black between playlist items), we have to reorder this code
slightly to make it work for video and images. Both are treated in the
same way. If both are enabled, video takes precedence.
As the UI module only depends on the common module, we can't direcly
add the ImageOutput to ExoPlayer. This is done via reflection if
the provided Player is an ExoPlayer.
#cherrypick
PiperOrigin-RevId: 643320666
This value is used in a follow-up change to re-order SEI messages
containing CEA-6/708 data from decode order to presentation order.
PiperOrigin-RevId: 643296338
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
This CL is a pure refactor of the existing tests, iterative changes
will be done in follow-ups.
The only logic change is having all MP4 assets have the presentaton of
height=360. The old code had some with height 480.
PiperOrigin-RevId: 643020773
Muxer never uses latest output position but always writes to
a specific location, so restoring its position does not add any
value.
PiperOrigin-RevId: 642996941
Previously, if renderFramesAutomatically = false, DefaultVideoFrameProcessor
may call onInputStreamProcessedListener after all frames have been
onOutputFrameAvailableForRendering, but before they had all been rendered and
freed.
Delay onInputStreamProcessedListener being called and subsequent DVFP
reconfiguration of effects, until all frames are rendered.
Tested using exoplayer setVideoEffects demo with playlist
PiperOrigin-RevId: 642963100
Determine `nextMediaSequence` and `nextPartIndex` based on the last `SegmentBaseHolder` instance, as it can update `mediaSequence` and `partIndex` depending on whether the HLS playlist has trailing parts or not.
Issue: androidx/media#1395
PiperOrigin-RevId: 642961141
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
Also move the track selection header strings to the demo app
as they are only used there (except for audio, which stays in UI)
PiperOrigin-RevId: 642616037
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
useHdr is unused option and doesn't make sense is the dynamic range of the overlay and video must match
Also reorders and adds javadoc in line with coding conventions
PiperOrigin-RevId: 642555396
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
Rational for keeping field package private:
Since the overall export already very complex, by looking at the output file
its hard to know if the desired processing happened or not. Since we now
support sequences with "n" media items, its even more important to know if all
the media items were processed or not.
Although the field exposes implementation details, it seems ok as we get benefit of detailed testing.
PiperOrigin-RevId: 642337888
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
This change adds `SessionError` and uses it in `SessionResult`
and `LibraryResult` to report errors to callers.
Constructors and factory method that used a simple `errorCode` to
construct error variants of `SessionResult` and `LibraryResult`
have been overloaded with a variant that uses a `SessionError`
instead. While these methods and constructors are supposed to be
deprecated, they aren't yet deprecated until the newly added
alternative is stabilized.
PiperOrigin-RevId: 642254336
This callback is useful for advanced use cases that care about
which Player calls are batched together. It can be implemented
by triggering this new callback every time a batch of Player
interactions from a controller finished executing.
PiperOrigin-RevId: 642189491
Previously these tests were setting the test-only `KEY_CONTROLLER`
bundle value to the prod value of
`MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG`, which is a bit
confusing because this is intended to be used as a `Bundle` **key**
(for a boolean value), and not a value itself.
Instead this CL creates a test-only value that can be used by
`RemoteMediaSession` and related test-only friends to indicate that
something (e.g. error or extras) should only be set on the notification
controller.
This CL also changes the logic in `MediaSessionProviderService` to
avoid needing to special-case checking for this controller key.
PiperOrigin-RevId: 641939283
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
Avoid scaling the lanczos windown function when scaling up.
When scaling up (output > input), we shouldn't scale the window
function or we risk not sampling any of the input pixels.
PiperOrigin-RevId: 641838149
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
Ensures valid progress state is returned. Should not return NOT_STARTED
once transformer.start has been called, until export ends.
PiperOrigin-RevId: 640533805
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
Removes the flakiness of
MediaItemExportTest.getProgress_unknownDuration_returnsConsistentStates
by using a longer input asset, such that ExoPlayer does not determine
the duration of the media.
PiperOrigin-RevId: 640502470
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
Add SeparableConvolution.configure(inputSize) to allow effect configuration
depending on input dimensions.
Add LanczosResample.scaleToFit method to scale input images to fit inside
given dimensions.
PiperOrigin-RevId: 640498008
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
fragment_shader_separable_convolution_es2.glsl had optimizations that assumed
all convolution coefficients are positive. Support negative coefficients,
and add tests.
PiperOrigin-RevId: 640104741
Before this change:
The only way to customize the icons was to override the drawables, e.g.
* `exo_styled_controls_play`
* `exo_styled_controls_pause`
However, that would set the drawables globally and prevent users from customizing the icons **per** PlayerView.
After the change, it is possible to provide drawable icons in the xml layout directly via `<androidx.media3.ui.PlayerView>` and
* `app:play_icon="@drawable/...`
* `app:pause_icon="@drawable/...`
* `app:vr_icon="@drawable/...`
* `app:fullscreen_exit_icon="@drawable/...`
* `app:next_icon="@drawable/...`
Note:
Two buttons that are left out of this change are fast-forward and rewind. They are more complicated due to layout insertion and customization with seek back/forward increments in the TextView.
Issue: androidx/media#1200
PiperOrigin-RevId: 639832741
These changes are possible because getProgress is no longer a blocking
operation on transformer.
* Tests call getProgress after every looper message executed.
* Use longer media assets for getProgress tests to give more progress
intervals.
* Remove conditional assertions.
PiperOrigin-RevId: 639734368
Switch from 4-channel RGBA_16F lookup texture to 1-channel R_16F.
Do not use a bitmap when creating the lookup table texture.
Instead, fill the texture directly.
Do not manually convert 32-bit float to 16-bit. Instead, let OpenGL
libraries do this for us.
PiperOrigin-RevId: 639717235
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
Foreground service type `mediaPlayback` requires permission `android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK`. The `MockMediaSessionService`, `LocalMockMediaSessionService`, `MockMediaLibraryService`
and `LocalMockMediaLibraryService` declared in the manifest are in the `mediaPlayback` type.
PiperOrigin-RevId: 639013810
AudioGraphInput.onMediaItemChanged is called on input thread. Pending
media item changes are processed on processing thread, inside calls to
getOutput().
This change allows multiple pending media item changes to be enqueued,
and processed in sequence.
PiperOrigin-RevId: 638995291
This is a relatively small change, and massively simplifies the work
needed for an app to consume Kotlin Multiplatform resources (without a
full `KmpResourceDataSource` implementation, which poses some
dependency challenges for now).
Issue: androidx/media#1405
PiperOrigin-RevId: 638991375
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
Both constants have the same value, but the method returning initial values for the media sequence/part uses `INDEX_UNSET`, so it makes sense to use it.
PiperOrigin-RevId: 638673282
Degammaing has been removed in cb4b2ea55c. The goldens for
TransformerHdrTest (previously TransformerSequenceEffectTestWithHdr)
were not regenerated because the test wasn't running due to its name
(fixed in e41a966237).
PiperOrigin-RevId: 638645635
Add DefaultVideosFrameProcessor experimental flag that controls
whether input Bitmaps are sampled once for a repeating sequence of
output frames with the same contents, or once for each output frame.
PiperOrigin-RevId: 637921350
Only sample from input bitmap when the input image has changed.
Introduce GainmapShaderProgram.newImmutableBitmap API that signals
input bitmap changes to GainmapShaderProgram (DefaultShaderProgram).
PiperOrigin-RevId: 637920207
This removes `throws Exception` from public methods in favour of more
specific exception types (`TimeoutException` and `PlaybackException`).
PiperOrigin-RevId: 637880546
Before this CL, externalShaderProgramInputCapacity was not reset when
the external shader program was reset (which occurs when the
InputSwitcher switches to an input with a different ColorInfo). This is
due to a regression introduced in bef3d518d2.
PiperOrigin-RevId: 637869215
Add a wait in DefaultCodec.signalEndOfInputStream when no
video encoder output has been seen. This avoids a thread synchronization problem
between writing frames to video surface, and signaling end of stream,
which was hit for video input of only one frame on some devices.
PiperOrigin-RevId: 637844690
PQ and HLG have different luminance ranges (max 10k nits and max 1k nits resp). In GL, colors work in a normalised 0 to 1 scale, so for PQ content, 1=10k nits and and for HLG content, 1=1k nits.
This cl scales and normalises PQ content appropriately so that all HDR content works in the HLG luminance range. This fixes two things
1. Conversions between HLG and PQ are "fixed" (before the output colors looked too bright or too dark depending on which way you are converting)
2. color-altering effects will be able to work consistently across HLG and PQ content
1 is tested in this cl. 2 will be tested when ultra HDR overlays are implemented, both cases have been manually tested to ensure the output looks correct on a screen.
PiperOrigin-RevId: 636851701
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
Remove redundant test logic to add file size to ExportResult because
the file size is already added to export result as part of an export
finishing.
PiperOrigin-RevId: 636499236
Add composition time offset parameter to TRUN box to
support muxing of videos containing B-frames by FragmentedMp4Muxer.
Update TRUN box version from 0 to 1 in order to manage signed
composition time offset.
PiperOrigin-RevId: 636426397
This is currently set from `Mp3Extractor.synchronizedHeader` which
gets overwritten every time we read a new frame. It seems safer to make
this defensive copy (and there will be at most one `XingFrame` instance
per-playback, so this is not prohibitively expensive).
PiperOrigin-RevId: 636181038
This change avoids a muxer deadlock when:
1. Sequence of items
2. First item has audio track that is shorter than video
3. Audio finishes, and muxer refuses to write more than 500ms of video
consecutively.
SequenceAssetLoader fails to progress to the second item. A muxer
deadlock is possible when the audio of the first item finishes,
audio end-of-stream is not propagated through AudioGraph, and muxer blocks
video, preventing SequenceAssetLoader to move to the next item in sequence.
By triggering silence generation early as soon as audio EOS is
encountered, we ensure SequenceAssetLoader can progress to the next item.
PiperOrigin-RevId: 636179966
`Info` header is used for CBR files, but in some cases not **every**
frame in these files is the same size. This change stops using the
single frame after the `Info` frame as the 'template' (and assuming all
subsequent frames are the same size/bitrate), and instead derives the
bitrate from fields in the `Info` header. This works for files which are
'almost' constant bitrate, like the one in Issue: androidx/media#1376 where every
frame is either 1044 or 1045 bytes except the one immediately after the
`Info` frame which is 104 bytes (32kbps), resulting in a wildly
incorrect duration calculation.
PiperOrigin-RevId: 636151605
This was previously only set on images because it was not ignored on
other media types. This parameter was made no-op for non-images in
7b2a1b4443.
PiperOrigin-RevId: 636078142
This change was originally made in 379cb3ba54.
It was then accidentally lost in when `Cea608Parser` was merged back
into `Cea608Decoder` in 25498b151b.
This was spotted when re-doing a similar lost change to `Cea708Decoder`,
reported in https://github.com/androidx/media/pull/1315.
See reasoning on e2847b3b80
about why this is the only 'lost' CEA-608 change.
PiperOrigin-RevId: 635803536
This change was originally made in 6f8249184b
It was then accidentally lost in when `Cea708Parser` was merged back
into `Cea708Decoder` in 51b4fa2cc8.
This is the only change made to the actual 'decoding' logic in
`Cea708Parser` between it being split from `Cea708Decoder` and merged
back in again, all the other changes in this period relate to the
implementation of the `SubtitleParser` interface, so don't need to be
preserved in `Cea708Decoder`:
51b4fa2cc8/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/Cea708Parser.java
`Cea608Parser` was also merged back into `Cea608Decoder` in
25498b151b
and so is vulnerable to the same risk of accidental loss of changes. To
be sure, I also checked the history of this file:
25498b151b/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/Cea608Parser.java
The only 'decoding logic' change there is 379cb3ba54,
which was also lost in 25498b151b.
I will send a separate change to resolve this.
PiperOrigin-RevId: 635796696
This shows ExoPlayer currently wrongly reports the duration of this
sample, because it assumes every frame is 32kbps (104 bytes) due to the
`PCUT` frame immediately after the `Info` frame.
A follow-up change will modify `Info` frame handling to resolve this
issue.
This sample was crafted using a hex editor to insert the additional
`PCUT` frame (the pattern of `null` and `x` is taken from the sample
file in Issue: androidx/media#1376, the header is modified to set the channel count
to 1 to match the rest of the file), and then update the frame count
and data size of the `Info` header to match.
Issue: androidx/media#1376
PiperOrigin-RevId: 635772837
Fragment shaders in OpenGL ES shader language aren't guaranteed
to support highp, required to correctly represent pixel coordinates
inside large images (e.g. 1920x1080).
This change moves coordinate mirroring for images out of fragment shader.
Fixes http://Issue: androidx/media#1331
PiperOrigin-RevId: 635732208
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
Gainmaps don't currently have an equals override, only reference equality is checked by Objects.equals(gainmap1, gainmap2). Create an equals method for gainmaps with the fields we care about to ensure we don't incur false positives in our equality checks.
PiperOrigin-RevId: 635510451
This is a fix for the fix in 319854d624. The original fix did
not reset the firstPeriodId to avoid any id clashes with future
updates. This however only works under the assumption that the
next manifest load at the next call to prepare() is exactly the
same as the current manifest. This is not true unless the call
happens very quickly (and may fail even then). Instead we should
keep the existing manifest directly as a reference so we can use
it to find the number of removed periods when we get a new manifest
at the next call to prepare().
Issue: androidx/media#1329
PiperOrigin-RevId: 634853524
This should be no-op overall and helps to disentangle the clock sync
update from the state of the manifest.
We currently check oldPeriodCount==0 to trigger the clock sync load,
which only works because the manifest happens to be null whenever
we need a new clock sync. We can decouple these concepts by directly
checking whether we have an existing elapsedRealtimeOffsetMs.
This also requires to set this value explicitly at the point where we
consider it set to the local device clock fallback when the timing
element load fails.
PiperOrigin-RevId: 634844921
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
For each item, AudioGraphInput now pads the input audio track with silence
to the duration given in onMediaItemChanged.
Possibly resolves Issue: androidx/media#921 .
PiperOrigin-RevId: 634753721
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
ExoPlayer sometimes calls AudioSink.playToEndOfStream before configuring
the sink. Before this CL, the composition player was failing if this
happened.
PiperOrigin-RevId: 634306592
Fix "subtitles rendered with border and no fill color" problem:
https://github.com/moneytoo/Player/issues/413
because '0' means it's an index to the palette table, not an RGBA value of 0
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
This class is not ready for production app usage yet, so it is still
marked `@RestrictTo(LIBRARY_GROUP)` for now. Apps can experiment with it
in a non-prod context by suppressing the associated lint error.
* Issue: androidx/media#1014
* Issue: androidx/media#1185
* Issue: androidx/media#816
PiperOrigin-RevId: 633921353
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
Also make one class truly package-private and keep the comment instead.
This comment should only appear on elements with default (package-private) visibility.
PiperOrigin-RevId: 633911914
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 change resets the error in the platform error state immediately
to make sure that the custom error is reflected only very briefly
and then gets back to the playback state that actually reflects the
player state.
Issue: androidx/media#543
PiperOrigin-RevId: 633626180
This treats heic as a separate mimetype to heif (even though heic files are a subset of heif files). This is in line with other platform classes like android.content.ContentResolver
https://developer.android.com/media/platform/supported-formats#image-formats was updated to include avif support or API level 34, so added this MimeType as well and updated our associated util.
solves Issue: androidx/media#1373
PiperOrigin-RevId: 633616214
This allows apps to better detect when the platform
reclaims a codec. This requires adding the error code
to MediaCodecDecoderException.
PiperOrigin-RevId: 633588914
Add ctts box implementation to handle muxing B-frame videos.
Add method convertPresentationTimestampsToCompositionOffset to
provide sample offsets. Return empty ctts box in case of video
does not contain B-frame. Add ctts box to MoovStructure to handle
muxing the video containing B-frames.
PiperOrigin-RevId: 633537106
https://truth.dev/faq#java8
Also use this change to remove most test usages of
`Lists.transform(...)` and replace them with `.stream().map(...)`.
PiperOrigin-RevId: 633523904
Also add documentation that suggests to use them in
PriorityTaskManager and adjust codec priorities in
Transformer's DefaultDe/EncoderFactory accordingly.
PiperOrigin-RevId: 633272667
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