This avoids cases where audio focus is never successfully acquired
because another app is holding on to transient audio focus indefinitely.
Issue: #7182
PiperOrigin-RevId: 305108528
When ClippingMediaPeriod first tried to read a buffer, if its end
position was before the end of the stream and it was buffered to its end
position, it would sometimes erroneously signal end-of-stream for
protected content because the sample queue might be waiting for DRM keys
at this point.
Work around the issue temporarily by signaling this specific case back
to ClippingMediaPeriod via the DecoderInputBuffer.
There will likely be a cleaner fix as a result of adding support for
dynamic clip end points in the future, at which point this can be
reverted.
issue:#7188
PiperOrigin-RevId: 305081757
It's interesting WebVTT explicitly handles line & position differently
in horizontal-rl/lr and vertical-lr/rl contexts. position is always
measured from the left of the viewport, even for rtl text, but line in
vertical-rl is measured from the right of the viewport.
We don't have to make Cue match WebVTT (I can go change the WebVTT
decoding instead) but it seems a reasonable 'default' to follow.
PiperOrigin-RevId: 304353900
ExoPlayer needs a codec to decide among WEBVTT and TTML decoder mimeType.
Apple describes IMSC1 in MP4 in
[RFC-8216 Section 3.6](https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-04#section-3.6).
The DASH manifest specifies the SMPTE-TT captions in the codecs in the manifest
(from W3C [TTML Profiles for Internet Media Subtitles and Captions 1.1](https://www.w3.org/TR/ttml-imsc1.1/#general-0).
DASH just doesn't require the rendition linking, but HLS does.
Apple implies the CODECS attribute of the variant needs to be do this. That is
with SHOULD and MAY language to imply the codec to use for it in the
[Authoring Guidelines](https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices)
This change defaults to WebVTT if no codec is specifed (same as current behavior) otherwise it picks it from the variants
referencing the media.
Without this, URL-encoding is assumed, which means ampersand-codes are
not carried through to the underlying web page correctly.
PiperOrigin-RevId: 304163733
HlsSampleStreamWrapper currently calls HlsMediaChunk.init, which calls back
to HlsSampleStraemWrapper.init. This re-entrancy seems a bit confusing.
PiperOrigin-RevId: 304139462
Selection of a passthrough codec will rarely (if ever) need to be customized, so
remove this capability from MediaCodecInfo.
Applications can still customize whether passthrough is used by overriding
MediaCodecAudioRenderer.usePassthrough, which now also checks for a passthrough
codec.
#exo-offload
PiperOrigin-RevId: 303964682
This is used to generate the initialization vector for encrypting the
cache contents.
Startblock:
<unknown commit> is submitted
and then
3w have passed
PiperOrigin-RevId: 303932151
This avoids massive changes to method signatures to add throws. Also, took suggestion to make it an `IllegalStateException`.
Move the catch outside of the finally that sets `nextLoadPosition` (this allows for possible recovery by reseting the `Extractor` and `TimestampAdjuster`).
Lastly, took the suggestion to make a minimum value for the tolerance (especially usefull for very short i-Frame only segments).
CharSequence is used by Notification builders and allows to set Spannable text.
It's the base interface of the String class, so apps wouldn't be break after
the update.
PiperOrigin-RevId: 303731890
This is required to align google3's stub (currently marked non-null) with Checker Framework's.
More information: go/matcher-nullness-lsc
Tested:
TAP train for global presubmit queue
http://test/OCL:303344687:BASE:303326748:1585344475427:29edc250
PiperOrigin-RevId: 303709053
- They are always listed with their canonical names
- Considering aliases means that blacklisting a decoder can end up
not actually blacklisting it, since it may still be accessible
via an alias. It also means that our decoder fallback logic can
end up falling back to a decoder that we've already tried!
PiperOrigin-RevId: 303348297
This callback will be deprecated, so moving all usages to better callbacks.
Some usages are still remaining that are less straight-forward to update.
PiperOrigin-RevId: 303298834
OnSeekProcessed is documented to be called as soon as all neccessary state changes
as a result of the seek have been made. As we now mask the state changes directly
when calling seekTo, we can also call this callback immediately without changing
the semantics of the method.
Our tests often use this callback as a way to wait for the internal player
to receive all pending commands and then report back. This is a special test
requirement for cases where we want to make sure no further updates happen as
a result of the player handling commands. To facilitate that, a new action is
added with a more descriptive name that achieves the same goal.
PiperOrigin-RevId: 303296210
This moves the playlist API methods to the Player interface. Implementation is moved from ExoPlayerImpl to BasePlayer where possible.
Further the CastPlayer is changed to implement the Player interface. Proper migration of the Playermanager to not use the ConcatenatingMediaSource anymore follows in a separate, future CL.
PiperOrigin-RevId: 302937779
Most of these are no longer needed since aa9eb5abc9
Cleanup change automatically generated by error-prone refactoring
//java/com/google/devtools/staticanalysis/errorprone:UnnecessaryJavacSuppressWarnings_refactoring on targets third_party/java_src/android_libs/exoplayer/v2/... java/com/google/android/libraries/exoplayer/v2/...
PiperOrigin-RevId: 302916092
This is less confusing than having audio processing functionality (e.g., playback
speed adjustment) just "not work" for some pieces of media.
If this change is merged, I will update #6749 to also track making DefaultAudioSink
intelligently enable/disable float output depending on how the audio processors are
configured.
Issue: #7134
PiperOrigin-RevId: 302871568
We currently have multiple places in ExoPlayerImpl that assign PlaybackInfo
instances and then inform listeners of all current changes. This is not ideal
because it causes multiple issues:
1. Some changes may easily be forgotten, e.g. there are clearly some checks
missing to see if isPlaying changed (e.g. in seekTo or setMediaSources)
2. Some callbacks didn't check if the value actually changed before sending
the callback (e.g. for the timeline change in setMediaSources - if the
timeline is still the same, we shouldn't send a onTimelineChanged event).
3. Having multiple callbacks in a single Runnable changes the order of
listener invocations slightly: Currently all events for one listener will
be send first before moving to the next listener. It should however send
a single event to all listeners first before moving to the next event.
All these issues can be solved by always using updatePlaybackInfo and never
assigning playbackInfo directly in another place.
Some tests needed to be updated as well because of issues (2) and (3). Also
added a new test to cover issue (1).
PiperOrigin-RevId: 302844981
It's incorrect to use an AudioFormat returned from AudioProcessor.configure
unless the AudioProcessor is active.
Issue: #7134
PiperOrigin-RevId: 302674132
This is a no-op for DefaultAudioSink for now, because DefaultAudioSink
currently disables processing anyway if the input uses ENCODING_PCM_FLOAT.
Issue: #7134
PiperOrigin-RevId: 302670534
androidTest of core already has the dependency on its main. Without this
exclude, gradle complains about type duplication when merging dex saying
"Type X is defined multiple times".
PiperOrigin-RevId: 302641585
If the start time of the edit falls within a sample, start from that
sample rather than the next one. This ensures playback can start from
the correct point if the sample is a keyframe, rather than having to
start from the next one.
Issue: #7133
PiperOrigin-RevId: 302639115
- Show renderers with no tracks in EventLogger track logging
- Log renderer names in EventLogger track logging
- Add useful message to ExoPlaybackException instances (including
renderer name for renderer errors)
PiperOrigin-RevId: 302421616
If MaskingMediaSource masks a multi-window media source, it may be that a period
is removed while we are using an initial unprepared masking MediaPeriod. That
means it's not guaranteed that a timeline update still contains our
unpreparedMaskingMediaPeriod and we should ignore timeline updates where the
period is no longer present because the it will be removed anyway.
PiperOrigin-RevId: 302383787
- This change also adds support for VideoFrameMetadataListener in the
AV1 renderer
- This is a preliminary step prior to adding FfmpegVideoDecoder
Issue: #2159
PiperOrigin-RevId: 301702460
This is a necessary step for Decoder implementations to support
audio and video. MediaCodecRenderer.DecoderException is renamed
MediaCodecDecoderException and extends the new DecoderException
Issue: #2159
PiperOrigin-RevId: 301698238
We have two known scenarios where the app could create an OOM error and
we want to handle it gracefully:
1. The app continues to allocate memory but doesn't make any progress
in the buffered position. OOM should be prevented by the default
load control and it should eventually throw an exception.
2. An extractor tries to allocate a large amount of memory on the
Loader thread based on information it read in faulty media files.
In this case we should attempt to play remaining media and then
throw an exception.
Both cases are already handled correctly, but we don't have any tests
ensuring that we don't introduce regressions.
PiperOrigin-RevId: 301585700
This removes a workaround that always continues buffering and instead
detects if the LoadControl returns false even though we don't have
any buffer. If enabled by a flag, this condition throws an exception.
PiperOrigin-RevId: 301584239
The restriction that these classes only work with SimpleDecoders
is unnecessary. An FfmpegVideoRenderer will not be able to use a
SimpleDecoder, because the SimpleDecoder assumption that each input
buffer can be decoded immediately into a corresponding output is
not true for all video codecs that Ffmpeg supports (e.g., H264 does
not have this property). Generalizing SimpleDecoderVideoRenderer to
DecoderVideoRenderer will allow FfmpegVideoRenderer to still use
the base class, without having to use a SimpleDecoder.
This is a preliminary change toward being able to merge a version
of https://github.com/google/ExoPlayer/pull/7079.
Issue: #2159
PiperOrigin-RevId: 301412344
The test is flkay (2/1000 runs) because the decoder initialization
before and after the seek are not perfectly deterministic. I couldn't
find a way to make them deterministic, so slightly chaning the test
setup instead. The test setup change doesn't affect the scenario being
tested.
PiperOrigin-RevId: 301390491
When no tracks are selected (or only tracks of unknown type), the
target buffer size is calculated to be 0. This means the player
won't request to buffer more data, nor can it start playback and
will be stuck forever.
PiperOrigin-RevId: 301374229
The assertion about the expected formats doesn't really belong in a
fake, the assertions should be closer to the test method.
This gets in the way when I try and write a new test in
AnalyticsCollectorTest that doesn't use the expected, constant Format
(because i want to specify drmInitData) - but changing the expected
Format is tricky because it's hard-coded into the FakeVideoRenderer
inner class.
I replaced the assertion in FakeRenderer with assertions in test
methods that used to assert on the format count.
PiperOrigin-RevId: 301353072
Previously calling removeListener would remove all instances of that
listener. Now it only removes a single instance.
This probably should have been part of introducing the Multiset:
2bd4d61b9b
PiperOrigin-RevId: 301191940
Without this change there's confusing behaviour if you pass e.g.
AnalyticsCollector (which implements both DrmSessionEventListener and
MediaSourceEventListener) to MediaSource.addEventListener: It will
receive DRM events too, even though you never passed it to
MediaSource.addDrmEventListener.
Also add some tests for MediaSourceEventDispatcher.
PiperOrigin-RevId: 301169915
This prevents OOM errors for high bitrate streams that attempt to fill
the buffer regardless of the memory usage.
Also change the max buffer sizes to ensure this is a no-op for video
streams < 20Mbps and audio streams < 260kbps.
Issue:#6647
Issue:#7006
PiperOrigin-RevId: 300720299
After this change users of ExoPlayerImpl and SimpleExoPlayer can use the media item base playlist API which converts the media item to a media source.
It adds the media item based methods to the ExoPlayer instead of the Player interface. This avoids a big change in the CastPlayer which requires migrating the cast extension to the MediaItem of the core module (follow up CLs).
PiperOrigin-RevId: 300575567
This CL removes the prefixes to the tests added after a6d0caaa3c.
This CL is generated by following command
$ find -name '*Test.java' | xargs -I{} sed -i 's/^\ \ public\ void\ test\([A-Z]\)\(.*\)$/ public void \L\1\E\2/' {}
PiperOrigin-RevId: 300547504
This avoids duplicate events being dispatched to object foo if
addListener(foo) is called more than once.
Part of issue:#6765
PiperOrigin-RevId: 300529733
We currently have the following logic to update renderers during
period transitions:
1. Wait for the currently reading period to finish reading all its
streams.
a. Advance reading period.
b. Set all streams that can't be replaced to final.
c. If streams can be replaced, replace them now.
2. Wait until playback position reaches the transition point
a. Disable all unneeded renderers (or those that need
re-enabling).
b. Advance playing period.
c. Enable all new renderers (i.e. all except the ones where
we replaced streams directly in step 1c.
This logic causes delays because steps 2a and 2c can easily happen
before 2b. Doing this allows a smooth transition for cases where
renderers change or where they need to be re-enabled.
The new order after this change is:
1. Wait for currently reading period to finish reading.
a. Advance reading period.
b. Set all streams that can't be replaced to final.
2. Update reading renderers iteratively.
a. If streams can be replaced, replace them asap.
b. If renderes need to be disabled, do so as soon as the
respective renderer ended.
c. Once step b is fully finished, enable or re-enable all new
renderers.
3. Wait unril playback position reaches the transition point AND
all tasks in step 2 are done (i.e. all renderers are set up for the
playing period).
a. Advance playing period.
As a nice side effect, decoder enabled and disabled events are now
always reported for the reading period, which is more consistent with
other renderer callbacks.
PiperOrigin-RevId: 300526983
This list was meant to simplify some usages where we only want to
make operations on enabled renderers. However, keeping this list
up-to-date is slightly error-prone (because renderers aren't added
and removed from this list next to the corresponding enable and disable
calls) and it makes it hard to do more fine-grained changes that only
enable or disabled a single renderer at a time.
PiperOrigin-RevId: 300513788
After this change MediaClocks and ExoPlayerImplInternal don't depend on the deprecated PlaybackParameter anymore but only know about playbackSpeed.
PiperOrigin-RevId: 300428791
This change deprecates the PlaybackParameters and remove the skipSilenceField from the PlaybackParameters. This implies that enabling and disabling skipping silences needs to be done on the Player.AudioComponent after this change.
After submission of the change, all Player API changes are done which are required to bring playbackSpeed and skipSilenceEnabled in the converged Player API state.
PiperOrigin-RevId: 300420843
In the HLS Spec (https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-04#section-4.4.3.6), specifically this or condition of this statement:
"... defined by the EXT-X-MAP tag, or is located between the start of the resource
and the offset of the first I-frame segment in that resource."
Change adds code to add this "implicit" Media Initialization Segment if no EXT-X-MAP defines one explicitly.
Pull in change to default to not use i-Frames for base AdaptiveTrackSelection.
The expectation is a subclases, that support transitioning to iFrame, will select these tracks.
This was a change suggested by @ojw28 to allow adpative track selection to work with IFrame only `Variant` as any other adaptive seleted `Track` in the `TrackGroup`. This actually works quite well with the exceptions that:
1. IFrame only tracks do not contain the same Rendition Group references as other non-iframe only varaints (so track selection should disable these tracks even in other non-video renderers.
2. Adapting to iFrame tracks only based on bandwidth might not be so good (as often larger spacial resolution iFrame track might have higher bitrate then lower spacial resolution non-iframe only track).
This change includes one proposed workaround in the AdaptiveTrackSelection class (only use iFrame for higher playback speeds).
Backout making the original `FormatAdjustingSampleQueue` an outer class and combining the new timestamp checking logic. This way the diff from `HlsSampleStreamWrapper` to dev-v2 are easier to see.
Update with code review suggestions:
1. rename to HlsCheckedSampleQueue to HlsSampleQueue and combine with format adjusting class.
2. Copywrite in added classes
3. Capture additional items useful for recovery and reporting in the exception class
4. Remove extraneous logging
5. eliminate magic number (50 seconds) and use percentage of duration
WIP:
- eliminate null check for chunk (chunkless prepare starts load before sampleQueue are created)
- work out recovery strategy
Add a SampleQueue subclass that checks the timestamp range of media samples queued to it and reports an exception on load if the timestamp is outside of spec bounds.
(Smashed to a single commit prior to rebase)
*** Original commit ***
Rollback of 949bbcfb2e
*** Original commit ***
Add masking for playWhenReady.
Masking is needed as soon as updates to a value can happen both in EPI
and EPII. PlayWhenReady is currently not masked because all updates
happen in EPI only. As soon as we allow pausing at certain times
(e.g. end of a stream), playWhenReady c...
***
PiperOrigin-RevId: 300330307
*** Original commit ***
Add masking for playWhenReady.
Masking is needed as soon as updates to a value can happen both in EPI
and EPII. PlayWhenReady is currently not masked because all updates
happen in EPI only. As soon as we allow pausing at certain times
(e.g. end of a stream), playWhenReady changes may be triggered by EPII
as well and that's why we need masking.
To know when the value actually changed, we also need to update the
internal state to include whether playback is supppressed.
***
PiperOrigin-RevId: 300303307
Masking is needed as soon as updates to a value can happen both in EPI
and EPII. PlayWhenReady is currently not masked because all updates
happen in EPI only. As soon as we allow pausing at certain times
(e.g. end of a stream), playWhenReady changes may be triggered by EPII
as well and that's why we need masking.
To know when the value actually changed, we also need to update the
internal state to include whether playback is supppressed.
PiperOrigin-RevId: 300284613
Exceeding the period duration may mean that that playback transitions
to another item even if the player is currently paused.
PiperOrigin-RevId: 300133655
There is no need for that, updating them is often forgotten and
takes up too much line space. Replace by a single TAG per test class.
PiperOrigin-RevId: 300113072
This change uses mime types in a functionally equivalent way to how we used the extension hint so far.
Using a mimeType instead of the extension has some advantages. Most importantly mimeTypes are used by the cast SDK with which we want to achieve interoperability in the cast extension.
Using a mimeType instead of the extension hint further appears to be a bit more clear (which might be opinionated). Further mime types are a well known and widely used concept to identify file type on the internet and it provides asterix based generalizations (audio/*, */*) which could express the media type OTHER that ExoPlayer is using internally (no usage of asterix required so far though).
PiperOrigin-RevId: 300058945
handlePrepare/Stop/SetPlayReady can be merged together as they all
handle changes to the desires state of the player.
Also, simplify parts of the control flow by not mixing code that
determines if audio focus needs to be handled with code that actually
acquires or abandons the focus.
PiperOrigin-RevId: 299824857
Without this option it's impossible to merge periods covering
different timestamps (at least not without playback issues).
Issue:issue:#6103
PiperOrigin-RevId: 299817540
The new version fixes some warnings in Gradle builds. Also
add missing indirect compileOnly dependencies to fix some more warnings
Issue:issue:#7007
PiperOrigin-RevId: 298855510