The previous API allowed to pass in null to the constructors although variants
without listeners exist. That's why we need to handle these null values.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191577891
Partial rollback of [] which caused b/77294898 by deleting a public Exoplayer API.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191519591
Previously it was necessary to create a new Sonic instance every time the
processor was flushed. Add a flush() method to Sonic so that it can be reused
when seeking. It still needs to be recreated when parameters change.
SonicAudioProcessor and SilenceSkippingAudioProcessor have methods for setting
parameters that are documented as taking effect after a call to flush(), but
actually the value returned by isActive() was updated immediately. Track the
pending values and apply them in flush() to fix this.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191442336
We currently refresh repeatedly in this case. According to the
DASH spec omitting minUpdatePeriod indicates that the manifest
does not change, and therefore we should not refresh. I think
it might be valid to omit minUpdatePeriod in a dynamic manifest
if relying exclusively on EMSGs to trigger manifest refresh.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191420247
applyContentMetadataMutations and getContentMetadata methods suppossed to be synchronized and assert the instance isn't released.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191419637
This is in preparation for making it possible to flush a Sonic instance so that
it's not necessary to create new ones every time the processor is flushed.
There should be no behavior changes here.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191410326
To be immediately rolled back after submission
Submitting on behalf of cblay.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191128111
Weirdly, the Android Javadoc indicates that it returns something
before the API level on which the same Javadoc states it was added.
In any case, we can simply not call the method to avoid the
warning, since we only use the value if the API level is at least
23 anyway.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190941776
Video renderers assume that the player position is advancing linearly while in
the started state. MediaCodecVideoRenderer schedules frames for rendering in the
future in the expectation that the player position is advancing.
This assumption is not currently true when using a position from the AudioTrack:
the player position can be fixed for (in the worst case) up to about 100 ms
before it starts increasing. This leads to an effect where the first frame is
rendered then a few other frames are rendered, then there's a pause before
frames start being rendered smoothly.
Work around this issue by checking whether the position has started advancing
before scheduling frames to be rendered in the future.
It might be preferable to make the audio renderer only become ready when its
timestamp can start advancing, but this is likely to be complicated.
Issue: #3841
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190937429
In audio processors an audio frame consists of a sample (which is 2 bytes for
16-bit PCM) for each channel. Sonic used "sample" to refer to this.
We've already diverged from the original source for Sonic quite a bit (deleting
code and making stylistic changes) and there haven't been upstream changes so
far, so it seems fine to start making more substantial changes here.
There should be no behavior changes here.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190916793
Use string concatenation for Metadata.Entry instances, and add
Util.formatInvariant for numerical formatting.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190915643
This adds two options to the ClippingMediaSource which allow proper clipping
of live streams:
1. The clipping stays fixed relative to already created media periods. That
means that playback actually progresses through the clipped media and
eventually reaches the end of the clipping. The window is also marked
as non-dynamic to let playback end in this case.
2. Allow to specify a clipping duration relative to the default position to
be able to specify the duration of live stream which is to be played.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190911049
*** Reason for rollback ***
b/76391022 was caused by a timestamp correction in StabilizableSimpleExoPlayer which will be fixed with this CL.
*** Original change description ***
Automated g4 rollback of changelist 189570277.
*** Reason for rollback ***
causes b/76391022, motion still playback in Photos is broken
*** Original change description ***
Used fixed time frame in clipping media period.
Currently, whenever the clipping is updated, we move the time frame of the
clipped period to start at 0. This causes problems when we are already playing
this period and the renderer position does no longer match the stream
positions.
This change keeps the time frame of the...
***
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190906020
- Ensure that no memory is used by audio processors that are always inactive, by
only allocating in flush() if active. If data was already allocated but a
processor becomes inactive we assume that the allocation may be needed in
future so do not remove it (e.g., in the case of ResamplingAudioProcessor).
- Make SilenceSkippingAudioProcessor set up its buffers in flush(), and clarify
that it is always necessary to call flush() if configure() returns true.
- Make reset() reset all state for all processors.
- Use @Nullable state or empty arrays for inactive audio processor buffers.
- Miscellaneous style/consistency cleanup.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190895783
This uses a simple threshold-based algorithm for classifying audio frames as
silent, and removes silences from input audio that last longer than a given
duration.
The plan is to expose this functionality via PlaybackParameters in a later
change.
Issue: #2635
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190737027
They don't really belong there; it was basically a convenience
thing where one of the arguments to the track selector was being
packaged up in the result to avoid having to hold a separate
reference to it.
This change is being made as a precursor to a subsequent change
where creating the TrackSelectorResult will move from
MappingTrackSelector to DefaultTrackSelector. DefaultTrackSelector
doesn't currently have access to the un-mapped tracks, and so is
unable to create a TrackSelectorResult. It's IMO preferable to
keep it that way rather than passing them down just so they can
be included in the result.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190640594
*** Reason for rollback ***
causes b/76391022, motion still playback in Photos is broken
*** Original change description ***
Used fixed time frame in clipping media period.
Currently, whenever the clipping is updated, we move the time frame of the
clipped period to start at 0. This causes problems when we are already playing
this period and the renderer position does no longer match the stream
positions.
This change keeps the time frame of the clipped media period as it is and
instead specifies the offset of the window in the period.
***
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190628272
Erroneous condition:
===================
If the track selection contains a subset of the available variants in the
master playlist, but only the selected variants return 404, the playlist
tracker will never propagate the error.
Fix:
====
The Chunk source will propagate the playlist load error if no more
alternative playlists are available (because all are already blacklisted).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190624484
Currently, MediaPeriod states that continueLoading may be called
during preparation. Some implementations would throw an error if
this happened.
Also make MediaPeriod documentation clearer.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190596870
If the AudioTimestamp was sampled before play() was called, it was incorrectly
returned to the caller for sanity-checking. Fix this behavior by dropping the
timestamp internally in the AudioTimestampPoller.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190584412
This change enables feeding decoders from the closest sync frame
before a specified seek position, where-as previously we'd
always feed decoders from the start of the chunk. This avoids
decoding and discarding many audio samples during each seek. The
same benefit also applies to video chunks containing more than
one key-frame.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190539547
This will allow SimpleExoPlayer to auto-register its own listener before the
drm session manager is used to set-up the renderers.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190478174
This adds callbacks for creating, releasing, and starting to read from media
periods.
Such events allow listeners to keep a list of active media periods. This is
useful to determine when no further events for a certain media period are
expected. It also allows listeners to associate renderer events unambigiously
with a reading media period.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190462717
And in ContentMetadata javadoc emphasize that it's a snapshot.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190461436
This gives the MediaSourceEventListener API a consistent look when new methods are
added which only have a window index and media period id.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190450270
This was only needed to ensure a ClippingMediaSource can provide samples from
a key frame before the clipping start time. Now the ClippingMediaSource will
not report negative timestamps, this workaround can be removed.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190045302
This will never happen in practice, since CEA608 shouldn't be encrypted (and we
can't handle it if it is), but in theory appendSampleEncryptionData can be called,
then skipFully can throw when applying the CEA608 transformation, then when
retrying appendSampleEncryptionData will be called again for the same sample.
appendSampleEncryptionData consumes from trackFragment.sampleEncryptionData, and
so the second time around data is being consumed one sample ahead.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189931631
The ad events are independent of the other media source events. Also,
registering the listener to the internal ad media sources will report the
regular media source events twice: once directly (with a non-ad media period
id) and once through the wrapping ads source (with the correct ad media period
id).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189905561
Also convert left side from milliseconds to microseconds for comparison
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189784833
Add logic to poll AudioTimestamp at different rates depending on when
playback starts and how the audio timestamp advances.
This fixes a pause about 500 ms after starting playback that occurs on some
devices and also makes our polling interval match the recommendations of the
AudioTrack documentation.
Issue: #3830
Issue: #3841
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189765200
When creating DeferredMediaPeriods, we don't know the actual timeline yet and
thus the default position is also unknown. We can still forward the correct
default position by forwarding it the deferred media period as soon as it
becomes known.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189763460
As part of pausing DefaultAudioSink, its position-related fields are reset. If
the audio timestamp API was in use, this results in falling back to the
getPlaybackHeadPosition API, which (on some devices) can lead to a jump in the
reported position.
Sample the position before pausing instead of after, to avoid this jump.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189713376
This is achieved by automatically registering a listener for child sources in
compositions. The composite media source has the chance to correct the
reported window index and media period id in the MediaLoadData of the events.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189575414
Currently, whenever the clipping is updated, we move the time frame of the
clipped period to start at 0. This causes problems when we are already playing
this period and the renderer position does no longer match the stream
positions.
This change keeps the time frame of the clipped media period as it is and
instead specifies the offset of the window in the period.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189570277
DefaultAudioSink had a lot of code related to tracking the position of the
underlying AudioTrack, and working around issues with the position APIs.
Move this code to a separate class responsible for position tracking. This is in
preparation for improving the audio timestamp polling behavior.
This change is intended not to cause any behavior changes.
Issue: #3841
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189344743
This allows to test sending events when using fake media sources.
The FakeMediaSource now simulates a manifest load when being prepared.
And the FakeMediaPeriod simulates a media load when being prepared.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189205285
Currently, we are treating all codecs starting with "mp4a" as AAC. However,
some codec strings starting with "mp4a" are not AAC format, as should be
treated differently.
GitHub: #3779
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189163517
This is a step towards factoring out position tracking functionality.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189155624
This is a first step towards factoring out position tracking functionality.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189027731
This allows to distinguish between media source events of multi-window and
multi-period media sources. In this change, only media sources currently reporting
events are changed. Proper support in composite sources will be added in a later
change.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188847366
This change also simplifies reporting the right media source events in a
future change.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188718504
This is achieved by moving the listener registration and the creation of the
event dispatcher into BaseMediaSource.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188461932
As it turns out there isn't much gain by subclassing
AbstractContentMetadata. Moved abstract onChange method to a listener
interface.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188353673
This allows to keep the same window sequence number if playback fails and
is then retried without resetting the position.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188339509
The value is increased to 50 seconds. With that the player can better handle
short network problems. This does NOT increase the maximum memory used as we
still apply the seperate DEFAULT_TARGET_BUFFER_BYTES.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188335603
When creating a new AC-3 passthrough AudioTrack the position
may advance from an old AudioTrack's position. The workaround
checked for the playback head position returning to zero, but
a subsequent change meant that we'd always start writing data
to the new track immediately (rather than waiting for its
position to 'stabilize' at zero).
Fix the issue by using the AudioTrack position directly. (Nb.
this doesn't handle the case of the stale position before
unwrapping being zero, but it is very unlikely to occur.)
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188319795
Also simplified shouldContinueLoading condition code and added a builder for DefaultLoadControl.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188306213
This allows to know the duration immediately and fixes the temporary unknown
duration in the UI when repreparing the same extractor media source.
The isSeekable property is still reset to false as we can't actually seek
until the seek map has been reloaded.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188145860
Also remove logic for tracking the next output buffer in LibvpxVideoRenderer, as
this allowed many consecutive frames to be rendered that were actually late
after dropping to keyframe. It looks better to show frames at a consistent
100 ms rate.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188144739
The playback state in ExoPlayerImpl and ExoPlayerImplInternal is usually kept
in sync. Only the timeline was so far not updated in the same way with the
internal player using a null timeline while ExoPlayerImpl keeps the previous
timeline.
This change removes the need to keep a null timeline which allows to update
the internal timeline in the same way as the external one. This fixes problems
when retrying a failed playback multiple times.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188034988
The start position was set to the old start position instead of the current
playback position. We need to set the start position to the current playback
position to ensure a repreperation with the same media starts from the last
playback position.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188025439
Previously, child source ids were reassigned when the media source is reused.
Now the creation of the ids moved to outer level to stay in sync with the list
of child media sources.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188014739
This restores functionality that was lost when we added
support for general timed message delivery.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187866807
This value can now be set in the DefaultBandwidthMeter instead. As a result
NO_VALUE can be removed from BandwidthMeter as we now always provide an
estimate.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187865341
This simplifies clearing a playlist without having to call removeMediaSource
repeatedly. It will also update the timeline only once.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187863857
There is a large number of repeated arguments in the callback methods of
MediaSourceEventListener. Grouping them into load related data and media
related data allows to significantly reduce the amount of boiler plate code
and also simplifies future extensions of either set of data.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187857252
This value is logically part of the bandwidth estimation and will eventually be
moved there from the adaptive track selection.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187597038
Before this change, HlsMediaSource timelines had a period starting at the epoch.
For VOD streams the window position in the period was the program date time.
This change makes period and initial window positions match. For live streams
the window position advances as segments are removed, so its position in the
period is the difference between the initial program date time and the program
date time of the latest playlist.
This also makes it possible to insert ads in VOD HLS content with program date
time, as the period and window are now aligned.
Issue: #3865
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187590948
1. Allow retaining a decoder without any reconfiguration, in addition
to retaining with reconfiguration (and not retaining)
2. Fix retention logic for video decoders to take into account changing
ColorInfo
3. Allow retention of audio decoders when possible
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187500285
Added a note about using TextureView only on hardware accelerated window.
Issue: #3901
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187498594
Currently, AspectRatioFrameLayout may need to resize itself if it could not
satisfy a target aspect ratio. User may want to know when this happen, or
whether this can happen, so they can update their UI accordingly. For
example: show/hide a button to toggle different resize mode only when the
aspect ratio of the view and the content is very different.
GitHub: #3736
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187484241
- Change 'compile' configuration (deprecared) to using 'implementation'
and 'api' configurations instead.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187311778
The non-dynamic media source has a strict subset of features of the dynamic one and
thus can be replaced.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187299432
Without child sources, the timeline can't possibly updated again within the
current looper message. Thus, we can send the empty timeline immediately.
This fixes a recently introduced flakiness in the test.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187295700
ClippingMediaSource provides a timeline where the period and window have the
same start/end positions, so when clipping a child timeline with a non-zero
offset between the window and period it is necessary to clear the offset then
apply the offset to the start/end positions used in the ClippingMediaPeriod.
Also add a message to clipping exceptions.
Also fix adjustment of seeks to the start of the clipped view.
Issue: #3888
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187292506
This is achieved by adding a BaseMediaSource which keeps a reference count of the
number of times the source has been prepared and forwards to the actual implementations
only once, such that only minimal changes are needed for each media source.
Issue:#3498
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187186691
Up to now we use a boolean "preventListenerNotification" to suppress updates
while other operations are still in progress. This ensures, for example, that
only one initial timeline is issued even for multiple child sources.
As soon as we allow to reuse the same instance, it becomes increasingly difficult
to manage this manual listener notification suppression. Therefore, this change
schedules an update as a new message on the playback thread immediately after the
current message. This way, we also ensure that all simultaneous updates within one
looper message iteration are reported together.
Issue:#3498
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187180342
The util package is, in practice, for things that are misc enough
to not warrant their own package. If something is deserving of a
package, it's IMO best placed somewhere else (I know you could
argue it's a util, but you could argue that about almost anything
else as well).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187010018
Allow the position to jump on receiving the first presentable input buffer,
if and only if the buffer timestamp differs significantly from what was
expected. This prevents a stuck buffering case for streams that are thought
to start at t=0, but actually start at t=large_value.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=186990214
The waiting for a ConditionVariable to be false was replaced by a
CountDownLatch whose count is asserted to be one. The timeout of a
ConditionVariable doesn't work in Robolectric unless someone is
manually increasing the SystemClock time.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=186003125
If an exception is thrown in an IMA callback it crashes the process with lots of
logging from WebView (including several stack traces, etc.). This change wraps
ImaAdsLoader code that might throw, skips any remaining ads (as the errors are
not recoverable, in general) and notifies a new load error callback so that the
application can implement its own handling. The intention is to make the loader
robust to unexpected requests from IMA and avoid crashes.
Also handle IMA loading an ad in an ad group that has no available ads. In rare
cases IMA will try to load an ad for which an error was previously notified, so
this drops those load requests allowing playback of the content to continue.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185985850
All media periods are part of a queue of windows buffered and played by
ExoPlayer. When repeating windows, the current MediaPeriodId is insufficient
to distinguish between the repetitions of the same period. This makes it hard
to see to which media period load events belong to, and it is also difficult to
determine whether two media periods belong to the same logical window or
whether they are part of different repetitions of the same window.
Therefore this change adds a unique sequence number to each window in the
sequence of windows and this sequence number is saved as part of the
MediaPeriodId.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185829509
Also added comments for all existing devices for easier reference.
Issue:#3835
Issue:#3236
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185661900
Also make ad group skipping more robust. After calling onError for an ad, IMA
will sometimes trigger an ad group load error, so this needs to be handled in a
way that allows some ads to be loaded already for the ad group.
This change also fixes calculation of the expected ad index to take into account
whether the position is being faked to trigger loading an ad or is the actual
player position.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185655844
Releasing the player released the internal playback thread once renderers were
released. Releasing a MediaPeriod queued a Loader.ReleaseTask on the loading
thread which would post back to the playback thread. If the playback thread had
been quit by the time this happened, the release task wouldn't be run.
Release on the loading thread instead of the playback thread. This avoids
needing to block releasing the player until the loading threads have ended, and
ensures that release tasks will run eventually. As part of this change,
ExtractorMediaPeriod's call to Extractor.release will now run on the loading
thread (which means that all Extractor methods are called on that thread) and
other cleanup in ReleaseCallback will run on the loading thread instead of the
playback thread.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185651320
There are 4 tests which can't currently be moved:
- DownloadManagerTest explicitly uses the main looper which isn't easily
supported because the test runs on this thread.
- ContentDataSourceTest uses an AssetFileDescriptor which wraps a
ParcelFileDescriptor. It seems Robolectric doesn't correctly forward the
inner wrapped file descriptor leading to NPE.
- CacheContentIndexTest and SimpleCacheSpanTest both work fine with Gradle
but fail with seemingly valid test failures on Blaze.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185366678
If the period uid doesn't match, the update procedure currently doesn't
remove the correct periods. This may cause the player to get stuck or to play
the wrong periods.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185129503
Allow skipping an ad group when requested by IMA, even if we aren't currently
playing one, to handle cases where no ads in an ad group will load (so IMA
requests resuming content but we never managed to start playing an ad).
Use the known ad group index (rather than the expected one) when handling ad
group load errors. This ensures we skip the right ad group if we notify IMA of
playback errors for every ad in the ad group, then IMA notifies that the ad
group is empty via a load error.
Also make some other miscellaneous small fixes to ads code:
- Avoid warning about unexpected ad group indices more than once.
- Output a warning if the ad count in an ad group decreases.
- Remove unnecessary assertion.
- Fix getting the ad duration for ad indices that haven't loaded yet.
- Allow setting an ad group state to its current value.
- Fix javadoc for setting the ad resume position.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184831495
The ad index in the ad group may need to skip over ads that failed to load, so
it can't just be incremented any more.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184812556
This feature is supported in the ConcatenatingMediaSource and is easily copied to this
media source. Also adding tests to check whether the atomic property works in normal
concatenation and in also in nested use.
Also fixes a bug where timeline methods of the DeferredTimeline were not correctly
forwarded.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184526881
This could happen when a media source is removed from a
DynamicConcatenatingMediaSource and one of its media periods is still active.
This media period is only removed by the player after the player received
a timeline update and thus we shouldn't release the removed child source
as long as it has active media periods.
Issue:#3796
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184522836
Resolve the media period for ad playback when resolving a subsequent period and
when receiving a timeline where the playing period in range (but wasn't before).
Fix the seek position calculation when a current ad must be skipped and is
followed by another ad.
Check MediaPeriodInfos match when checking MediaPeriodHolders, to handle cases
where a future ad should no longer be played. This may involve playing two
content media periods consecutively.
Issue: #3584
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184514558
DefaultExtractorInput.SCRATCH_SPACE buffer is used to skip data by
reading it into this buffer and discarding.
Simultaneous use of skip methods corrupts this buffer. Normally the
read data is discarded so it doesn't matter but the underlying
DataSource may use the buffer too. If it's a CacheDataSource it uses
this buffer to read data from upstream then write to cache.
Issue: #3762
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184502170
This avoids reading a format that is not equal because of switching between
NO_VALUE and 0.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184298076
This makes assertion errors in code running on the Looper less easy to miss.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184294290
For below API level 16, the logic copied from ConnectivityManagerCompat.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184131406
Helper class to create notifications for downloads using DownloadManager.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183225948
Even if a developer synchronizes every method, thread safety is still not guaranteed
because the internal callback methods can't be synced from outside.
Issue:#3773
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184122072
1. Add string for STATE_CANCELED. Lint doesn't like that the
switch statement on the state IntDef doesn't have a case
for STATE_CANCELED. May as well add one, even if we're not
planning on our demo app showing notifications for this
state.
2. Replace non-human-readable error message with one provided
by ErrorMessageProvider.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184120892
In the case of the components we deliberately access via
reflection, it's normal that they might not be resolved
due to proguarding (i.e. if the app isn't being built to
include them). Don't note their omission.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184120611
Lint recommends switching to SparseArray<X> instead.
This is done for the DASH case. For the Cast case it's
easier to use a switch statement.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184119312
I think (?) they're harmless, but lint doesn't like them.
Using them within the class body means the TargetApi
annotation applies, which makes lint happy.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184117951
In MediaCodecRenderer, we currently uses codec.getInput/OutputBuffers event
though these APIs are deprecated and are not recommended from API 21+. This
change makes sure that:
- On API 20 and below, we will keep using codec.getInput/OutputBuffers.
- On API 21+, we will use getInput/OutputBuffer(index) APIs instead.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184112329
*** Reason for rollback ***
Broke everything
*** Original change description ***
Clean up message naming in EPII
***
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184061352
This applies when PlayerControlView is used as a standalone
component (not inside PlayerView). Previously hideAtMs was
set to 0, which caused the view to be immediatley hidden in
onAttachedToWindow. After this change the first time the view
is attached to the window is effectively treated as a "user
interaction" for the purposes of deciding when to timeout.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184056324
This make sure all media sources can be reprepared after being released.
Issue:#3498
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183990416
When the dynamic media source contains multiple empty timelines in a row and some
of them dynamically change to a non-empty timeline, the window and period indices
are not updated correctly because the index of the changed child source is wrong.
To fix this bug, the child index is added to the media period holder to have direct
access on the current child index to prevent ambiguity.
Furthermore, the uid is changed to be the hash code of the MediaSourceHolder not the
MediaSource itself to allow adding the same MediaSource twice without violating the
unique uid policy.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183973462
Also fixes a bug where deferred media periods were kept in the list for
an unprepared media source although the media period was already released.
Issue:#3498
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183800889
This enables caching manifest files for DASH, HLS and SmoothStreaming.
To disable caching a non cache DataSource should be provided for reading
manifest to the used MediaSource.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183794252
In startReadWrite*() methods a new CachedContent is created if the there
isn't one already for the given key. If the span is release without
writing any content, this fix removes the added CachedContent.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183666821
Before this change, the ad playback state stored the number of played ads in
each ad group. There was no way to represent that an ad had failed to load (and
it wouldn't be possible just to increment the played ad count to signal a load
error because there might be an unplayed ad before the ad that failed to load).
Represent the state of each ad (unavailable, available, skipped, played, error)
in each ad group. In a later change the player will use this information to
update its loaded MediaPeriods in response to future ads failing to load.
Also make the AdPlaybackState immutable and remove copying/duplication of its
fields in the ad timeline and period.
Issue: #3584
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183655308
For our strings to be translated, we're required to provide
added context in the form of a description, and specify a
maximum length for the translated strings.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183651515
1. When we try and load something via reflection and find the
class, always throw rather than failing silently if we
subsequently fail to instantiate an instance. This is
indicative of a broken proguard setup, and failing silently
makes it hard to spot.
2. Add library/core proguard configuration to ensure extension
renderer constructors that we access via reflection are kept.
3. Add demos/main proguard configuration to ensure ImaAdsLoader
constructor that we access via reflection is kept.
4. Added IMA proguard file to hopefully fix#3723, although I
wasn't actually able to reproduce the issue.
Issue: #3723
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183648187
- Renderers becoming ready is asynchronous, so the change wasn't
well thought through :(.
- This will bring back the possibility of getting stuck in the
buffering-but-not-loading anything state. This will need to be
addressed in a future CL.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183646837
100ms is unrealistically short and, for example, causes the player to buffer
many periods ahead when looping.
Previously this was not feasible, because ExoPlayerTest as instrumentation test
actually needed to wait for the realtime playback duration.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183646772
MediaPeriodInfoSequence has functionality for determining what MediaPeriod
should be loaded next. Move this into the queue as an initial step towards
moving logic concerning updating the queue of media periods out of
ExoPlayerImplInternal.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183391114
This removes some boiler-plate code for compostite sources and will also
simplify resuing media source in the future (because this class can keep track
of child listeners).
Issue:#3498
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183387123
This is only allowed for user-replaced manifest uris. If the manifest
itself forwards to another manifest, we keep the original manifest in
case the forwarding changes.
Also removed the initialManifest as it can be simplified by using the
sideloadedManifest indicator.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183376209
When SsMediaSource loads Manifest, it dispatches loadCompleted event even when
the load is cancelled. This change makes sure SsMediaSource dispatch
loadCancelled event instead.
GitHub: #3754
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183241940
Since AspectRatioFrameLayout supports zoom mode as another resize_mode,
PlayerView's resize mode xml attribute should include this as well.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183237663
Helper class to create notifications for downloads using DownloadManager.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183225948
- This gives LoadControl enough information in shouldContinueLoading
to know whether returning false will result in a terminal non-playback
state.
- DefaultLoadControl will always return true when returning false will
result in a terminal non-playback state, unless the target buffer size
is exceeded. This can help to avoid getting stuck in the case that a
MediaPeriod is providing samples from an unexpected starting time.
- Make the terminal state actually terminal. Previously the player would
end up in an indefinite buffering state. We now fail with an error.
- Also remove the opportunity for LoadControl implementations to livelock
playback. No sane LoadControl should simultaneously tell the player that
it doesn't want to load anything and that it doesn't want to start
playback. So this change removes the opportunity and starts playback in
EPII instead in this case.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183114797
Try to delay failure for as long as possible. That is, propagate
DRM session failures only after an encrypted buffer arrives or clear
sample playback without session is not allowed.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183076348
setBytesRemaining() doesn't work when called after closeCurrentSource()
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182999254
These parsers can be used to get a manifest which includes only the
representations identified by the given keys.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182932874
So far this wasn't possible because Robolectric's Looper and MessageQueue
implementations have multiple shortcomings:
1. The message loop of new HandlerThreads is an not an actual loop and
scheduled messages are executed on the thread the message is enqueued
(not the handler thread).
2. The scheduler used to replace the message queue is synchronizing all its
methods. Thus, when a test attempts to add messages to a Handler from
two different threads, it may easily run into a deadlock.
3. The scheduler doesn't correctly emulate the order of messages as they
would be in an actual MessageQueue:
a. If the message is enqueued on the handler thread, it gets executed
immediately (and not after all other messages at the same time).
b. The list of messages is always re-sorted by time, meaning that the
order of execution for messages at the same time is indeterminate.
4. Robolectric's SystemClock implementation returns the current scheduler
time of the main UI thread. So, unless this scheduler is used to add
messages in the future, the SystemClock time never advances.
This CL adds two helper classes which extend and replace Robolectric's
ShadowLooper and ShadowMessageQueue.
1. We intercept messages being enqueued or deleted in the message queue.
Thus Robolectric's faulty scheduler gets never used. Instead, we keep
a blocking priority queue of messages, sorted first by execution time
and then by FIFO order to correctly emulate the real MessageQueue.
2. We also keep a list of deleted messages to know which messages to ignore
when they come up in the looper.
3. When a new Looper is started, we override the dummy loop to an actual
eternal while loop which waits for new messages, checks if they haven't
been deleted, and runs the messages (similar to what Robolectric's
MessageQueue would have done at this point).
Because we don't actually use the main UI thread in our tests, we can't rely
on the SystemClock to progress in any sensible manner. To overcome this issue,
we can use the auto-advancing FakeClock also used for the simulation tests.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182912510
This achieves two things:
1. All our tests use the same type of assertions.
2. The tests currently run as instrumentation test can be moved to
Robolectric without changing the assertions.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182910542
These were caused by two issues:
1. The FakeMediaSource can be updated with a new timeline. The setNewSourceInfo
is called from a different thread than prepareSource and both access local
variables without synchronization.
2. For multi-window playback, the FakeRenderer claims that isReady and isEnded
are both set to false if it read the end of the stream. However isReady should be
true because it is able to "render" its data until the end of the stream.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182785169
When a loaded DASH manifest is invalid (either some periods were removed
illegally, or a manifest for a live event is stale), we will retry using 1
logic:
- Retry loading with back-off up-to a limit.
- Throw a DashManifestExpiredException() if we exceed retry limit.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182770028
Also disable use of dummy surface for devices that require the
workaround. It's only useful in the case that we can use
setOutputSurfaceWorkaround, so if it's disabled the dummy surface
has no purpose (it actually makes things worse by consuming past
the key-frame prior to the current position, which doesn't happen
if you have no surface at all).
Issue: #3724
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182750068
This fixes a very specific case where the data read has non-cached gaps
and a read-only CDS switches to read from upstream in a gap then the
cached data is deleted. When the CDS reaches the end of the gap, it
tries to open the next source. As there is no cached data, it tries to
continue with the already opened upstream data source but as it reached
end of the gap range, the code starts looping.
Also fixes infinite lock which occurs when in the previous case CDS isn't
readonly. It locks the content while filling the gap in the cache. At the
end of the gap, as the following data is deleted it tries to lock the
content for writing but the content is already locked by itself.
The last fix is preventing removal of CachedContent entry from
CachedContentIndex while associated key is locked.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182595426
Some tests in ExoPlayerTest issue commands to the player from the test thread
while the player is actively playing media (playWhenReady=true). Due to the
indeterminate time taken to enqueue the commands on the playback thread, they
may arrive when the player already proceeded to another window or finished
playback.
To ensure the tests are always deterministic, this change pauses playback in
the tests where this may happen before issuing the commands.
Also, for tests where we need to wait for a new window before issuing the
next command, a new action is added which allows to play until a specified
position.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182535096
- Get handling of "stale" and "out of sync" manifests so
they're right next to each other (to be merged)
- Move startLoadingManifest to be next to the methods that
schedule it, and actually start loading stuff.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182530683
As soon as the seek gets acknowledged by EPII, EPI returns the actual position
from the playback info again which is set by EPII. Thus, EPII needs to update
the position to reflect the changes expected by EPI.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182515106
- In IDLE, the button will now call a preparer. This allows
removal of the separate retry button from the demo app.
- In ENDED, the button will seek back to the default position
and play.
- Behavior is made consistent with LeanbackPlayerAdapter.
Issue: #3689
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182506855
When determining the next sample to load, the Mp4Extractor now takes
into account how far one stream is reading ahead of the others.
If one stream is reading ahead more than a threshold (default: 10 seconds),
the extractor continues reading the other stream even though it needs
to reload the source at a new position.
GitHub:#3481
GitHub:#3214
GitHub:#3670
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182504396
It seems good to have EventLogger available from the library.
In particular because when app developers use it and then
submit bug reports, it makes it much easier to work out what
happened. It will also allow EventLogger to be used across
our (now multiple) demo apps.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182389407
This gets rid of the manual tracking of this queue with reading, playing,
and loading period holders. Still keeping these names for queue access methods.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182378944
This solves the problem of having dense tracks' ids change.
For example, if the available variants offer both HEVC and AVC video
tracks, all video samples will map to the same sample queue even if
IDs don't match.
Issue:#3653
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182070486
This avoids issues that can arise due to slight discrepancies between
chunk start times (obtained from the manifest of segment index) and
the timestamps of the samples contained within those chunks.
Issue: #2882
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182054959