Starting with Android 13 (API 33) an app needs to request the
permission to post notifications or notifications are suppressed.
This change documents this in the class level JavaDoc of the
`DownloadService`.
Issue: google/ExoPlayer#10884
PiperOrigin-RevId: 501346908
(cherry picked from commit 055ed77433)
Initialising the fields as Integer and then getting a String on compute
time is slow. Instead we directly initialise these fields as String.
Improves the time taken in bundling PlayerInfo further to less than
200ms from ~300ms.
Also modified a test to improve productive coverage.
PiperOrigin-RevId: 500003935
(cherry picked from commit d49437c6e1)
The tunneling callbacks are sent via Handler messages and may be
handled after the codec/surface was changed or released.
We already guard against the codec/surface change condition by
creating a new listener and verifying that the current callback
happens for the correct listener instance, but we don't guard
against a released codec yet.
PiperOrigin-RevId: 495882353
(cherry picked from commit 5e23b8bfd5)
Some Player methods operate relative to existing indices in the
playlist (add,remove,move,seek). As these operations may be issued
from a place with a stale playlist (e.g. a controller that sends
a command while the playlist is changing), we have to handle out-
of-bounds indices gracefully. In most cases this is already
documented and implemented correctly. However, some cases are not
documented and the existing player implementations don't handle
these cases consistently (or in some cases not even correctly).
PiperOrigin-RevId: 495856295
(cherry picked from commit a1c0b10482)
The `MediaItem` instances in the following cases are not actually empty but acts as a placeholder. `EMPTY_MEDIA_ITEM` can also be confused with `MediaItem.EMPTY`.
PiperOrigin-RevId: 495843012
(cherry picked from commit 74559b4a18)
BasePlayer simplifies implementations by handling all the various
seek methods and forwarding to a single method that can then be
implemented by subclasses. However, this loses the information about
the concrete entry point used for seeking, which is relevant when
the subclass wants to verify or filter by Player.Command. This
can be improved by adding the command as a new parameter. Since
we have to change the method anyway, we can also incorporate the
boolean flag about whether the current item is repeated to avoid
the separate method.
PiperOrigin-RevId: 494948094
(cherry picked from commit 6e0f1f10b3)
Some Player methods like getting the Looper and adding listeners
were always allowed to be called from any thread, but this is
undocumented. This change makes the threading rules of these
methods more explicit.
Removing listeners was never meant to be called from another thread
and we also don't support it safely because final callbacks may
be triggered from the wrong thread. To find potential issues, we
can assert the correct thread when releasing listeners.
Finally, there is a potential race condition when calling addListener
from a different thread at the same time as release, which may lead to
a registered listener that could receive callbacks after the player is
released.
PiperOrigin-RevId: 493843981
(cherry picked from commit e9364b0f6e)
This inconsistency was exposed by an upcoming change to deprecate
`POSITION_UNSET` in favour of `INDEX_UNSET` because position is an
ambiguous term between 'byte offset' and 'media position', as shown
here.
PiperOrigin-RevId: 492470241
(cherry picked from commit 2f8cf947c7)
Discovered while investigating Issue: google/ExoPlayer#10823
Example stack trace with the previous code (I added the index value for
debugging):
```
playerFailed [eventTime=44.07, mediaPos=44.01, window=0, period=0, errorCode=ERROR_CODE_FAILED_RUNTIME_CHECK
androidx.media3.exoplayer.ExoPlaybackException: Unexpected runtime error
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:202)
at android.os.Looper.loop(Looper.java:291)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.lang.IllegalArgumentException: index=-1
at androidx.media3.common.util.Assertions.checkArgument(Assertions.java:55)
at androidx.media3.extractor.text.webvtt.WebvttSubtitle.getEventTime(WebvttSubtitle.java:62)
at androidx.media3.extractor.text.SubtitleOutputBuffer.getEventTime(SubtitleOutputBuffer.java:56)
at androidx.media3.exoplayer.text.TextRenderer.getCurrentEventTimeUs(TextRenderer.java:435)
at androidx.media3.exoplayer.text.TextRenderer.render(TextRenderer.java:268)
at androidx.media3.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1008)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:509)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:202)
at android.os.Looper.loop(Looper.java:291)
at android.os.HandlerThread.run(HandlerThread.java:67)
]
```
#minor-release
PiperOrigin-RevId: 492464180
(cherry picked from commit 5f6fde4d2a)
Use the bitrate of the audio format (when available) in
DefaultAudioSink.AudioTrackBufferSizeProvider.getBufferSizeInBytes() to
calculate accurate buffer sizes for direct (passthrough) playbacks.
#minor-release
PiperOrigin-RevId: 491628530
(cherry picked from commit e219ac21ae)
To support OPUS offload, we need to provide a few configuration values
that are currently not set due to the lack of devices supporting
OPUS offload.
PiperOrigin-RevId: 491613716
(cherry picked from commit 4cf877b814)
Our FakeClock generally makes sure that playback tests are fully
deterministic. However, this fails if the test uses blocking waits
with clock.onThreadBlocked and where relevant Handlers are created
without using the clock.
To fix the flakiness, we can make the following adjustments:
- Use TestExoPlayerBuilder instead of legacy ExoPlayerTestRunner
to avoid onThreadBlocked calls. This also makes the tests more
readable.
- Use clock to create Handler for FakeVideoRenderer and
FakeAudioRenderer. Ideally, this should be passed through
RenderersFactory, but it's too disruptive given this is a
public API.
- Use clock for MediaSourceList and MediaPeriodQueue update
handler.
PiperOrigin-RevId: 490907495
(cherry picked from commit 7d62943bcd)
When estimating the AudioTrack min buffer size, we must use a PCM
frame of 1 when doing direct playback (passthrough). The code was
passing -1 (C.LENGTH_UNSET).
PiperOrigin-RevId: 489238392
(cherry picked from commit d9d716869b)
The method allows clients to specify a pre-existing thread
to use for playback. This can be used to run multiple ExoPlayer
instances on the same playback thread.
PiperOrigin-RevId: 488980749
(cherry picked from commit 79b809b556)
Added new method to check if codec just functionally supports a format. Changed getDecoderInfosSortedByFormatSupport to use new function to order by functional support. This allows decoders that only support functionally and are more preferred by the MediaCodecSelector to keep their preferred position in the sorted list.
UnitTests included
-Two MediaCodecVideoRenderer tests that verify hw vs sw does not have an effect on sort of the decoder list, it is only based on functional support
Issue: google/ExoPlayer#10604
PiperOrigin-RevId: 487779284
(cherry picked from commit 1eb8a6b36e)
This tag is only understood by Dackka, which is used to generate the media3 javadoc.
PiperOrigin-RevId: 489233200
(cherry picked from commit 058cba95d4)
This better matches the callback name (onSurfaceSizeChanged) and
probably cause less confusion with getVideoSize.
PiperOrigin-RevId: 488669786
(cherry picked from commit 8438daca1f)
Util.getAudioTrackChannelConfig() maps a channel count to a
channel mask that is passed to AudioTrack. The method expected that
playback of 8-channel audio is possible from Android 5.1 and playback of
12-channel audio is only possible from Android 12L. However, there is no
restriction on the upper number of channels that can be passed to the
AudioTrack. google/ExoPlayer#10701 is an example where the audio decoder
outputs 12 channels on an Android 10.
This change removes the restrictions for 8 and 12 channels. Note, we still
do not support playback of arbitrary number of channels as it would require
further changes to DefaultAudioSink.
#minor-release
Issue: google/ExoPlayer#10701
PiperOrigin-RevId: 488659831
(cherry picked from commit 1b24e6fd14)
We currently skip this calculation entirely, but it can be added by
calculating the window duration using the wrapped window's duration
and the provided AdPlaybackState.
Issue: google/ExoPlayer#10764
PiperOrigin-RevId: 488614767
(cherry picked from commit 20151b9930)
It's not clear to me why presubmit didn't catch this, I briefly
investigated but couldn't work it out - so I'm just going to fix
it and move on.
#minor-release
PiperOrigin-RevId: 487497827
(cherry picked from commit 13ee34facc)
This makes two types of fix:
1. Align parameter names on overridden methods where the superclass
has `@param` javadoc.
2. Use `@hide` on `protected final` methods that refer to package-private
types. This will hide these symbols from Dackka javadoc generation
but not (currently) from the artefacts distributed on Maven. These
methods are currently unusable outside their package anyway (e.g. by
external developers) because of the dependency on a package-private
type.
This also changes some HLS, SmoothStreaming, and IMA code where I've renamed
parameters of overridden methods to be consistent across the type
hierarchy.
#minor-release
PiperOrigin-RevId: 487472665
(cherry picked from commit 10c4a4dfc1)
This change makes adding ad events in live streams more robust by allowing ad
groups to grow in number of ads if more ad events are received than initially
announced by the SDK.
With the IMA prefetch feature, an AdPod can grow in size in certain conditions
like from initially 2 ads to 4 ads being part of the ad group. With this change,
if an additional ad event arrives while the ad group is still being played,
the ad group is expanded. If the event arrives late and the ad group is already
completed, a new group is created for the remaining ads.
This also covers the case where we join the live stream while an ad is being
played and we missed at least one LOADED event from the SDK. Ads of the group
before the first LOADED event are ignored in such a case.
PiperOrigin-RevId: 484214760
(cherry picked from commit 136addf640)
Split inner interface into separate file, which will go in common
module. The old interface will be deprecated and extends the new.
#cleanup
PiperOrigin-RevId: 483732226
(cherry picked from commit ad52b68c73)
Although it can be useful to check the output format, it's not required or needed.
For some AudioProcessor implementations, it is stated/obvious that
the output format will match the input, in which case there is no
a need to check the return value.
#cleanup
PiperOrigin-RevId: 483403679
(cherry picked from commit a7bfa12eec)
Currently, repeating the same item (via seekNext/Previous) implicitly
results in a seek to the default position of the current item, which
looks exactly the same as a direct seek. As a result, we don't send
onMediaItemTransition as we would for every other seekNext/Previous
call.
This can be fixed by explicitly marking the repeat case in the internal
BasePlayer/ExoPlayerImpl methods, so that the callback can be triggered.
Issue: google/ExoPlayer#10667
PiperOrigin-RevId: 481951788
(cherry picked from commit 76ce0cc69f)
We already have logic to end all session except the current one if the
current one doesn't have a MediaPeriodId yet. This is assuming that this
only happens after a seek on the app side where the player doesn't have
detailled knowledge about the MediaPeriodIds yet.
Currently this logic isn't triggered if the window we are coming from
doesn't have its MediaPeriodId either as we run into another check that
keeps sessions around until we have a valid windowSequenceNumber.
Swapping both conditions fixes this case without breaking any of the
other known transition scenarios.
Issue: androidx/media#180
PiperOrigin-RevId: 480866465
(cherry picked from commit 6070d9110a)
We currently use the literal -1 (=NO_VALUE) when adding up the
total. Tracks without known bitrate can be ignored in the
calculation, but we should use an explicit value of 0.
#minor-release
Issue: google/ExoPlayer#10664
PiperOrigin-RevId: 480048126
(cherry picked from commit af19e0ea89)
If the sample type is Dolby Vision and the display does not support Dolby Vision, then the capabilities DecoderSupport flag is set to DECODER_SUPPORT_FALLBACK_MIMETYPE. This denotes that the renderer will use a decoder for a fallback mimetype if possible. This alters track selection as tracks with DecoderSupport DECODER_SUPPORT_PRIMARY are preferred.
UnitTests included
-DefaultTrackSelector test that checks track selection reordering with DECODER_SUPPORT_FALLBACK_MIMETYPE
-MediaCodecVideoRenderer test that checks setting of DecoderSupport flag based on Display's Dolby Vision support
Issue: google/ExoPlayer#8944
PiperOrigin-RevId: 480040876
(cherry picked from commit a366590a04)
* Add `setOutputStreamOffsetUs(long)` method in `AudioSink`.
* Add private methods `setOutputStreamOffsetUs(long)` method in `MediaCodecRenderer` and `DecoderAudioRenderer`.
* Add protected method `onOutputStreamOffsetUs(long)` method in `MediaCodecRenderer`, in which:
* `MediaCodecRenderer` itself will be no-op for this method.
* `MediaCodecAudioRenderer` will propagate this value to its `audioSink`.
* Add logics in `DecoderAudioRenderer` to calculate `outputStreamOffsetUs`.
PiperOrigin-RevId: 479265429
(cherry picked from commit 4c73241058)
This allows to access the associated functionality of AudioTrack and
fills a feature gap to MediaPlayer, which has a similar method.
Issue: androidx/media#135
PiperOrigin-RevId: 476398964
(cherry picked from commit ccb820dd2f)