Access is package-private and it will allow the media controller logic
to interact with the underlying platform session directly if needed.
Interop: When a MediaController connects to an older session (before this
change), it won't get the platform token from the session directly.
Many controllers will be set up with a platform or compat token though
and we can simply keep the already known token and use it. The only
cases where we still don't have a platform token in the MediaController
are the cases where the controller is created with a SessionToken based
on a ComponentName.
PiperOrigin-RevId: 678230977
Some devices seem to throw an `IllegalArgumentException` when
attempting to set a valid media button broadcast receiver
for playback resumption. This change handles this exception
as a no-op to avoid crashing the app. As a result, playback
resumption with media keys isn't going to work on these
devices.
This change needs to be reverted once the root cause on these
devices has been fixed (see internal bug ref in source).
Issue: androidx/media#1730
PiperOrigin-RevId: 677904243
Allow apps to preload the first period of the next window in
the playlist of `ExoPlayer`. By default playlist preloading is
disabled. To enable preloading,
`ExoPlayer.setPreloadConfiguration(PreloadConfiguration)` can be
called.
`LoadControl` determines when to preload with its implemenation of `shouldContinuePreloading(timeline, mediaPeriodId, bufferedDurationUs)`.
The implementation in `DefaultLoadControl` allows preloading only when
the player isn't currently loading for playback. Apps can override this
behaviour.
Issue: androidx/media#468
PiperOrigin-RevId: 677786017
This CL adds `SonicTest` and `RandomParameterizedSonicTest` as
initial basic unit testing for `Sonic.java`. The tested scenarios
do not necessarily verify a correct implementation of Sonic, but rather
hope to catch any behaviour change from the current implementation.
The change includes a small fix for a lossy simplification and also
checks whether the output sample count matches the expected drift from
the truncation accumulation error present in Sonic's resampler. This is
important as pre-work for fixing issues with unexpected durations within
`SonicAudioProcessor` and `SpeedChangingAudioProcessor` that cause AV
sync issues for speed changing effects.
This is a partial roll forward of e88d6fe459, which was rolled back in
873d485056.
PiperOrigin-RevId: 677756854
AudioTrack doesn't automatically ramp up the volume after a flush
(only when resuming with play after a pause), which causes audible
pop sounds in most cases. The issue can be avoided by manually
applying a short 20ms volume ramp, the same duration used by the
platform for the automatic volume ramping where available.
Together with the already submitted 6147050b90, this fixes the
unwanted pop sounds for most cases in the desired way. It only
leaves two cases that are not handled perfectly:
- If the media file itself contains a volume ramp at the beginning,
we wouldn't need this additional ramping. Given the extremely
short duration, this seems ignorable and we can treat it as a
future feature request to mark the beginning of media in a special
way that can then disable the volume ramping.
- For seamless period transitions where we keep using the same
AudioTrack, we may still get a pop sound at the transition. To
solve this, we'd need a dedicated audio processor to either ramp
the end of media down and the beginning of the next item up, or
apply a very short cross-fade. Either way, we need new signalling
to identify cases where the media originates from the same source
and this effect should not be applied (e.g. when re-concatenating
clipped audio snippets from the same file).
PiperOrigin-RevId: 676860234
When sending a custom command with `browser.sendCustomCommand` when
connected to a legacy browser service, the custom command was delivered to `MediaSessionCompat.Callback.onCustomAction` instead of the service method
`onCustomAction`. The difference is that the service version can return an
async response with a bundle, while the session callback version doesn't
have a return value.
Hence, the service method was never called and it wasn't possible to send
a reponse or signal an error back to the browser. The resulting
`ListanableFuture` simply always immediately resolved to a success.
This change overrides `ListenableFuture<SessionResult> sendCustomCommand(SessionCommand command, Bundle args)` in
`MediaBrowserImplLegacy` to use the `MediaBrowserCompat` method to send
instead of the `MediaControlleCompat` method that was used by the subclass
`MediaControllerImplLegacy`. This involves the service callback instead of the
session callback and enables `MediaBrowser` to get the actual return value
from the legacy service.
Issue: androidx/media#1474
#cherrypick
PiperOrigin-RevId: 676519314
Last buffer was not flipped, so was writing the garbage data between
limit and capacity, rather than the actual data between position and
limit.
As a result, all PCM audio dump files need updating.
PiperOrigin-RevId: 676452990
- Added logic to parse media duration from the `mdhd` box for accurate frame rate calculation.
- Fallbacks to track duration from `tkhd` when `mdhd` contains invalid or missing data.
- Avoids incorrect frame rate calculations in MP4 files with an edit list (`elst`) box.
- Adds frame rate calculations for partially fragmented MP4 files.
- Verified accuracy with tools like `mediainfo` and `ffprobe`.
Issue: androidx/media#1531
**Note**: The slight difference in frame rate values in dump files that aren’t MP4s with an edit list or fragmented MP4s isn’t due to differences in `tkhd` and `mdhd` duration values (which should be identical for non-edited or non-fragmented files). Rather, it’s because they are calculated using different timescales. The `mvhd` box defines a global movie timescale, which is used for the track's `tkhd` duration. Meanwhile, each track’s `mdhd` box defines its own timescale specific to its content type, which we now use for more accurate frame rate calculation.
PiperOrigin-RevId: 676046744
This method is documented that it may only be called in `STATE_OPENED`
or `STATE_OPENED_WITH_KEYS`. It's possible for it to be called in other
states (like `STATE_ERROR`) without this guard.
Previously this didn't cause issues, but since 9d62845c45
we assume that the `sessionId` is non-null in this method, which results
in an `IllegalStateException` when the documented state restriction is
ignored.
PiperOrigin-RevId: 675969256
This is no longer needed now our `compileSdk` implies a new-enough AGP
which does this out-lining automatically via R8. See also
https://issuetracker.google.com/345472586#comment7
There's no plan to remove the `ApiXXX` classes, but no new ones need
to be added.
PiperOrigin-RevId: 675940634
This is to allow not setting the MediaFormat OPERATING_RATE and PRIORITY
altogether. The current behvaiour, if left the value `UNSET`, it'll apply the
our optimizations, but apps might want to disable this optimization.
PiperOrigin-RevId: 675923909
The Galaxy Tab S7 FE has a device issue that causes 60fps secure H264 streams to be marked as unsupported. This CL adds a workaround for this issue by checking the CDD required support for secure H264 in addition to the current check on standard H264. If the provided performance points do not cover the CDD requirement of support 720p H264 at 60fps, then it falls back to using legacy methods for checking frame rate and resolution support.
Issue: androidx/media#1619
PiperOrigin-RevId: 675920968
After the change in a879bc2154, the Sequence won't have repeated
EditedMediaItems. Thus if the sequence is looping, the last EditedMediaItems
in the Sequence object might not corresponds to the last item in the "logical"
sequence.
PiperOrigin-RevId: 675912197
NotificationChannel and NotificationChannelGroup are public APIs that were
added in Android O, so at this point it is okay to have them appear in API
signatures.
PiperOrigin-RevId: 675756005
The muxer might not have accepted the first sample, if it
is waiting for audio track.
This bug causes issue when
1. VideoSampleExporter gives first sample (timestamp = 0) to the muxer.
2. Muxer does not write it because its waiting for audio track.
3. The video pipleline has processed all the sample and they are ready
to be consumed.
4. VideoSampleExporter fetches the next available sample from encoder (which is still with timestamp = 0) but it changes its timestamp to last timestamp because VideoSampleExporter thinks it has muxed the sample at timestamp zero, but in reality it hasn't. This is because the flag `hasMuxedTimestampZero` is set when queueing the input, rather than actually muxing the input.
This scenario can happen when video is processed much faster than
the audio.
PiperOrigin-RevId: 675565603
Previously, track IDs were added to `trackIndicesPerSampleInQueuedOrder`
even when the sample was not committed. This caused issues where attempts
to read samples from the `SampleQueue` returned `C.RESULT_READ_NOTHING`,
which led to an exception being thrown due to the assumption that samples
were available to read.
This fix updates the logic to track sample commits by comparing the write index before and after calling `SampleQueue.sampleMetadata`. Track indices are only added if the sample was committed, ensuring accurate sample handling and avoiding exceptions.
PiperOrigin-RevId: 675526115
to
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS
This CL also combines LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER
and LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS.
The reason for combining the two enums is that, when the option
to use END_OF_STREAM_BUFFER is selected and if the EOS buffer is
not provided then the muxer anyways fallbacks to duplicate
duration behavior.
The last sample with 0 durations seems less useful so
change the default behavior to non-zero duration.
This will also match the behavior with MediaMuxer.
PiperOrigin-RevId: 675189932
To support for 3gpp h263 codec in Mp4Muxer currently profile and level is hardcoded and provided to h263 box. Parse profile and level from MediaFormat and use those value to write h263 box.
PiperOrigin-RevId: 675004590
The tests were flaky because CompositionPlayer registers audio sequences'
formats to the audio pipeline in first-come-first-serve order. With the change
in bc8d82355f, the audio format is deterministic.
The test is turned off in 060356ea00
PiperOrigin-RevId: 674261801
`PreloadMediaSource` allows to have a `startPositionUs` passed when `preload` is called, then in `PreloadControl.onContinueLoadingRequested`, it can be more intuitive to see the buffered duration rather than the absolute buffered position as the preload progress. Similar in `DefaultPreloadManager`, we haven't allowed the apps to set a custom start position for individual sources though, once we add this support, using the "duration from the start position" than the absolute position will be less error-prone, otherwise, it can run into a case that the position that the apps set is smaller than the start position.
PiperOrigin-RevId: 674251362
Sonic would accumulate truncation errors on float to int conversions
that caused the final output sample count to drift noticeably, by
hundreds of samples on streams of a few minutes of length. The fix now
keeps track of the truncation error and compensates for it.
Other small fixes include eliminating lossy operations (e.g. int
division) and using doubles instead of floats for resampling where
helpful.
This CL also introduces `SonicParameterizedTest`, which helps test
resampling on an arbitrary number of randomly generated parameters,
with random sample data. `SonicParameterizedTest` uses `BigDecimal`s
for calculating sample count values, as to avoid precision issues with
large sample counts.
PiperOrigin-RevId: 673852768
`CPU_FEATURES_COMPILED_ANY_ARM_NEON` is always defined when `CPU_FEATURES_ARCH_ARM` is but it can be defined as `0` or `1` ([cpu_features source](8e60d3f9be/include/cpu_features_macros.h (L237-L245))). This patch makes sure to use the value of `CPU_FEATURES_COMPILED_ANY_ARM_NEON` instead of whether it is defined or not.
PiperOrigin-RevId: 673837522
When processing edit lists in MP4 files, the media start position may be a non-keyframe. To ensure proper playback, the decoder must preroll to the preceding keyframe, as these preroll samples are essential for decoding but are not rendered.
Issue: google/ExoPlayer#1659
#cherrypick
PiperOrigin-RevId: 673457615
In case of negative PTS workaround, instead of disallowing all cases where samples are not in presentation order, we now validate that the first sample's presentation time is the smallest. This adjustment allows for correctly applying an offset to ensure all samples have a presentation time >= 0.
#cherrypick
PiperOrigin-RevId: 673434793
When converting NAL units from AnnexB to Avcc format,
one byte at a time was read. In fact many bytes were read
multiple times due to suboptimal logic.
Changed the logic to read 4 bytes at once and also to avoid
reading same bytes again.
This improved the time taken for writing a batch of 30
samples from 40ms to 20ms.
PiperOrigin-RevId: 673025781
In the current implementation due to missing "="
operator, last three bytes were not checked for
000 or 001 sequence.
In sample_no_bframes file, few samples has extra 0 at the end.
It was working fine with the bug because muxer was writing some
harmless 0 at the end.
PiperOrigin-RevId: 672994054
Avoids the dispatch of listener notifications of stream type/device volume change during construction of ExoPlayer. That was problematic because we end up blocking on `constructorFinished.blockUninterruptible()`
Issue: androidx/media#1692
PiperOrigin-RevId: 672965552
If the task executor handles an available frame (task submitted in the
SurfaceTexture listener) between the call to registerInputFrame() and
the execution of the task submitted in the method (in this CL), it
should be rejected.
PiperOrigin-RevId: 672903756
`Muxer` module needs to use this method, hence moved to common.
This CL also makes `getHevcProfileAndLevel` public because this is used
in `MediaCodecUtil`.
PiperOrigin-RevId: 671739166
Seeking was causing the player to hang in the following scenario:
1. The surfaceTexture's onFrameAvailableListener is called in
ExternalTextureManager to notify that a new frame is available.
2. This call submits a task on the GL thread.
3. A seek is performed and DefaultVideoFrameProcessor.flush() is called
before the task submitted in 2 is executed.
4. DefaultVideoFrameProcessor.flush() flushes the task executor, so that
the task submitted in 2 never gets executed.
5. Once the seek is over, the first frame is registered and rendered on
the surface texture.
6. Playback hangs because the onFrameAvailableListener is never called
for this new frame. This is because surfaceTexture.updateTexImage()
was never called on the frame that became available in 1.
This fix is making sure that the task submitted in 2 always gets executed.
Issue: androidx/media#1535
PiperOrigin-RevId: 671389215
Before this, because `Label.toString()` isn't implemented, the logged info
wasn't that useful:
```
labels=[androidx.media3.common.Label@6caac039]
```
With this change it's more useful:
```
labels=[en: english]
```
PiperOrigin-RevId: 671029474
The workaround causes issues with XML-based shared transitions, so we
can't apply it unilaterally.
Issue: androidx/media#1594
Issue: androidx/media#1237
PiperOrigin-RevId: 670960693
We have a tracking bug Issue: androidx/media#514 for supporting it, but issues like Issue: androidx/media#1542 still show that users stumble over it.
PiperOrigin-RevId: 670955189
Handling for `MediaCodec.CryptoException` was originally added only
around calls to `MediaCodec.queueSecureInputBuffer` and
`queueInputBuffer` (because these are the only methods that can throw
this exception). When asynchronous interaction with `MediaCodec` was
added in <unknown commit>, exceptions from `MediaCodec` started being stored
and bubbled out of **later** interactions with `MediaCodecAdapter`. This
means that `MediaCodecRenderer` can now see `CryptoException` thrown
from a different method, like
`MediaCodecAdapter.dequeueInputBufferIndex()`, and this ends up missing
the `catch (CryptoException)` code in `MediaCodecRenderer`. This results
in an "unexpected runtime error" stack trace like [A].
This change fixes the stack trace to:
1. Make it a "renderer exception" instead of "unexpected runtime error"
2. Include the correct DRM error code -> `@PlaybackException.ErrorCode`
mapping.
You can see the corrected stack trace below [B].
-----
[A] (synthesized from manually throwing a `CryptoException` from
`AsynchronousMediaCodecBufferEnqueuer#doQueueSecureInputBuffer`)
```
playerFailed [eventTime=11.56, mediaPos=10.35, window=0, period=0, errorCode=ERROR_CODE_UNSPECIFIED
androidx.media3.exoplayer.ExoPlaybackException: Unexpected runtime error
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:729)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
Caused by: android.media.MediaCodec$CryptoException: Test error message
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.doQueueSecureInputBuffer(AsynchronousMediaCodecBufferEnqueuer.java:232)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.doHandleMessage(AsynchronousMediaCodecBufferEnqueuer.java:196)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.access$000(AsynchronousMediaCodecBufferEnqueuer.java:47)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer$1.handleMessage(AsynchronousMediaCodecBufferEnqueuer.java:93)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
```
[B]
```
Playback error
androidx.media3.exoplayer.ExoPlaybackException: MediaCodecAudioRenderer error, index=1, format=Format(0, null, null, audio/mp4a-latm, mp4a.40.2, 134359, en, [-1, -1, -1.0, null], [2, 44100]), format_supported=YES
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:649)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
Caused by: android.media.MediaCodec$CryptoException: Test error message
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.doQueueSecureInputBuffer(AsynchronousMediaCodecBufferEnqueuer.java:232)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.doHandleMessage(AsynchronousMediaCodecBufferEnqueuer.java:196)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.access$000(AsynchronousMediaCodecBufferEnqueuer.java:47)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer$1.handleMessage(AsynchronousMediaCodecBufferEnqueuer.java:93)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
```
PiperOrigin-RevId: 670951229
Limit input image size in Transformer to be less than 4096x4096.
For very large images, this can reduce memory usage substantially,
and stays away from `GL_MAX_TEXTURE_SIZE` - often 4096
PiperOrigin-RevId: 670555939
These tests do not test performance. Moving them out of this directory
ensures they are run on emulators and on all physical devices.
PiperOrigin-RevId: 670505992
MediaMuxer doesn't support B-frame before API 25.
The fix is added only in those test which appeared in triage failure.
It can be added to other tests as they are discovered.
PiperOrigin-RevId: 670480966
To avoid `WrongConstant` failures with methods that expect
`C.@PcmEncoding`, `OUTPUT_PCM_ENCODING` now points to the constant in
`C` instead of `AudioFormat`.
#cherrypick
PiperOrigin-RevId: 670251463
These were missed when upgrading to both SDK 19 and 21, but they now
cause failures like:
```
Caused by: java.lang.RuntimeException: Failed to parse package buildout/intermediates/apk_for_local_test/debugUnitTest/packageDebugUnitTestForUnitTest/apk-for-local-test.ap_: buildout/intermediates/apk_for_local_test/debugUnitTest/packageDebugUnitTestForUnitTest/apk-for-local-test.ap_ (at Binary XML file line #20): Requires newer sdk version #21 (current version is #19)
at org.robolectric.shadows.ShadowPackageParser.callParsePackage(ShadowPackageParser.java:61)
... 20 more
```
#cherrypick
PiperOrigin-RevId: 670241471
Make ByteBufferGlEffect public.
Build a speed test, and end to end test that verify
frames can be copied to CPU-accessible ByteBuffer
PiperOrigin-RevId: 670213343
Disable assertions and make sure playback passes.
The flake is caused by having different sequences starting with MediaItems of
different audio format, and it's undefined behaviour as to which one CompositionPlayer chooses to use.
PiperOrigin-RevId: 670195113
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