The fLaC prefix is included in the initialization data output
from the MKV extractor, so this is highly likely ot be the
right thing to do.
Issue: #6397
PiperOrigin-RevId: 268244365
This allows to uniquely identify a window within a Timeline. The value is set
correctly for all Window instances, but is not used anywhere yet.
PiperOrigin-RevId: 267556516
We currently don't test if an ad needs to be played in case we are already
playing content.
This is to prevent recreating the current content period when
an ad is marked as skipped. We prefer playing until the designated ad group
position and appending another piece of content. This is less likely to cause
visible discontinuities in case the ad group position is at a key frame
boundary.
However, this means we currently miss updates that require us to play an ad
after a timeline update.
PiperOrigin-RevId: 267553459
Select a track with matching role flags even if someone specifies a preferred role flgs without providing a preferred language
Prefer track without captions or describing music and sound flag when no role flag preference is provided.
Removing this method requires custom MediaSource implementations to switch
to the new version. While this breaks the implmentation, it also avoids problems
with accidentely forwarding to the wrong method or with accidental stack
overflows when none of the two methods gets implemented.
It's unlikely any callers are affected because this is only the extended version
with the defaultProjectionPositionUs parameter that no caller except the
internal player will use.
PiperOrigin-RevId: 267323042
Include Dataspec.httpRequestHeaders in CronetDataSource,
and OkHttpDataSource. Updated documentation of
HttpDataSource.open() to suggest that it should set request
headers (in decreasing priority) from (1) the passed DataSpec,
(2) parameters set with setRequestProperty() and (3) default
parameters set in the HttpDataSource.Factory. No mechanism
has been put in place to enforce this.
PiperOrigin-RevId: 266895574
Sniffing is performed in ProgressiveMediaPeriod even if a single
extractor is provided. Skip it in that case to improve performances.
Issue:#6325
PiperOrigin-RevId: 266766373
The Javadoc for open() won't be read by anyone because it's an overridden method
of the interface and not called directly from application code.
Move doc to class documentation as this is a generic explanation about the
functionality of the class. Also added "all" to clarify that all the parameters
will be added and the order of preference just applies in case of key clashes.
PiperOrigin-RevId: 266753249
This is a no-op interim change to introduce key request error
handling customization. Following changes will allow users to
inject their own LoadErrorHandlingPolicy implementations.
Issue:#6334
PiperOrigin-RevId: 266344399
- Surface information provided by methods isHardwareAccelerated,
isSoftwareOnly and isVendor added in Android Q in MediaCodecInfo
class.
- Estimate this information based on the codec name for earlier API
levels.
Issue:#5839
PiperOrigin-RevId: 266334850
This generalizes our "does file still exist" check to also check
that the file is the expected length. If it's not, we don't trust
it. This avoids infinite recursion in CacheDataSource if a cache
file is truncated underneath the cache.
Issue: #6165
PiperOrigin-RevId: 265707928
Implementations of ForwardingTimeline may override any of the two variants of
this method. We need to ensure that the customized override is always called.
Add back the deprecated method and make it final to forward to the
non-deprecated method in all cases for ForwardingTimelines.
PiperOrigin-RevId: 265419830
The last selection criteria is the audio bitrate to prefer higher-quality
streams. We shouldn't apply this criterium though if the languages of the
tracks are different.
Issue:#6335
PiperOrigin-RevId: 265064756
The implementation can't work properly unless these methods are called by
subclasses, so annotate them to require calling the super implementation when
overriding.
PiperOrigin-RevId: 265017433
The error is closely related to the playback state IDLE and should be updated
in sync with the state to prevent unexpected event ordering and/or keeping the
error after re-preparation.
Issue:#5407
PiperOrigin-RevId: 265014630
Currently the value of FLAG_ALLOW_CACHE_FRAGMENTATION is defined as "1 << 4" but commented as "8". Either the value of FLAG_ALLOW_CACHE_FRAGMENTATION should be "1 << 3", or the comment should be 16. Here I am modifying the comment since it does not affect any current behavior.
PiperOrigin-RevId: 265011839
The app is able to pass a more specialized array type, so the Arrays.copyOf call
produces an array into which it's not valid to store arbitrary AudioProcessors.
Create a new array and copy into it to avoid this problem.
PiperOrigin-RevId: 264779164
Extract supplemental data from block additions in WebM/Matroska.
Allow storing supplemental data alongside samples in the SampleQueue and write
it as a separate field in DecoderInputBuffers.
Handle supplemental data in the VP9 extension by propagating it to the output
buffer.
Handle supplemental data for HDR10+ in MediaCodecVideoRenderer by passing it to
MediaCodec.setParameters, if supported by the component.
PiperOrigin-RevId: 264582805
There is no point in having this parameter as the tag should always be a single
immutable object instantiated at the time the Timeline is created or earlier.
So there is no preformance benefit and it's error-prone in case people
forget to set setTag=true.
PiperOrigin-RevId: 264117041
This solves various issues around event association for buffering and
error throwing around period discontinuities.
The main changes are:
- Logic around being "ready" at the end of a period no longer checks if the
next period is prepared.
- Advancing the playing period no longer checks if the next one is prepared.
- Prepare errors are always thrown for the playing period.
This changes the semantics and assumptions about the "playing" period:
1. The playing period can no longer assumed to be prepared.
2. We no longer have a case where the queue is non-empty and the playing or
reading periods are unassigned (=null).
Most other code changes ensure that these changed assumptions are handled.
Issue:#5407
PiperOrigin-RevId: 263776304
This matches the documentation on MetadataDecoder.decode:
"@return The decoded metadata object, or null if the metadata could not be decoded."
PiperOrigin-RevId: 263767144
Most users are likely to be only interested in the playlist items. So put the
Window definition first and explicitly mention that this is a playlist
item.
PiperOrigin-RevId: 263764515
The current ExoPlayerFactory is growing too big and usage becomes increasingly
complicated because it's not possible to set individual components without
specifying many other defaults.
Adding new builder classes makes building easier and more future-proof.
PiperOrigin-RevId: 263339078
entries are used in .equals(), so it's good to have them printed in toString() too (for test failures) and it makes logging easier too.
PiperOrigin-RevId: 263335503
The current max video buffer is 13MB which is too small for high quality
streams and doesn't allow the DefaultLoadControl to buffer up to its default
max buffer time of 50 seconds.
Also move util method and constants only used by DefaultLoadControl into this
class.
PiperOrigin-RevId: 263328088
I think we need to start clearing the holder as part of the
DRM rework. When we do this, it'll only be valid to read
from the holder immediately after it's been populated.
PiperOrigin-RevId: 262362725
We're no longer tied to the emsg spec, so we can skip unused fields
and assume ms for duration.
Also remove @Nullable annotation from EventMessageEncoder#encode, it
seems the current implementation never returns null
PiperOrigin-RevId: 262135009
We already allow mixed mime type and mixed sample rate adaptation on request,
so for completeness, we can also allow mixed channel count adaptation.
Issue:#6257
PiperOrigin-RevId: 261930046
This also decouples EventMessageEncoder's serialization schema from the emesg spec (it happens to still match the emsg-v0 spec, but this is no longer required).
PiperOrigin-RevId: 261877918
If we keep streams in chunk sources after selecting new tracks, we also keep
a reference to a stale disabled TrackSelection object. Fix this by updating
the TrackSelection object when keeping the stream. The static part of the
selection (i.e. the subset of selected tracks) stays the same in all cases.
Issue:#6256
PiperOrigin-RevId: 261696082
We currently keep the sequence number if we don't reset the position. However,
the sequence number should be kept if we don't reset the state. Otherwise
re-prepare with position reset is counted as new playback although it's still
the same.
PiperOrigin-RevId: 261644924
- When in STATE_SEEK with targetGranule==0, seeking would exit
without checking that the input was positioned at the correct
place.
- Seeking could fail due to trying to read beyond the end of the
stream.
- Seeking was not robust against IO errors during the skip phase
that occurs after the binary search has sufficiently converged.
PiperOrigin-RevId: 261317035
Two tests have very low propability flakiness (1:1000) due to not waiting for
a seek in one case and the chance of already being ended in another case.
Fix these and also adjust wrong comments about state changes.
PiperOrigin-RevId: 261309976
These values can easily default to the empty track group and the empty
selection. As a result we can remove restrictions about not calling
holder.getTrackGroups before the period finished preparation.
PiperOrigin-RevId: 261280927
A previous change switched to calculation of the bitrate based on the
first MPEG audio header in the stream. This had the effect of fixing
seeking to be consistent with playing from the start for streams where
every frame has the same padding value, but broke streams where the
encoder (correctly) modifies the padding value to match the declared
bitrate in the header.
Issue: #6238
PiperOrigin-RevId: 261163904
Android considers ALAC initialization data to consider of the magic
cookie only, where-as FFmpeg requires a full atom. Standardize around
the Android definition, since it makes more sense (the magic cookie
being contained within an atom is container specific, where-as the
decoder shouldn't care what container the media stream is carried in)
Issue: #5938
PiperOrigin-RevId: 261124155
Checking inputPosition == 0 isn't sufficient because the synchronization
at the top of read() may advance the input (i.e. in the case where there's
some garbage prior to the seek frame).
PiperOrigin-RevId: 261086901
This factory was only needed in the past when we didn't have
AnalyticsCollector.setPlayer. Code becomes easier to use without this factory.
PiperOrigin-RevId: 261081860
This new annotation declares everything as non-null by default and can be
used as a package annotation in package-info.java.
In this change the core lib offline package and the mediasession extension is
annotated that way as initial example usage.
PiperOrigin-RevId: 260894548
DefaultMediaClock has currently two non-ideal behaviours:
1. One part of checking if it should use the renderer clock is checking whether
the associated renderer finished reading its stream. This only makes sense
if the renderer isn't already reading ahead into the next period. This can
be solved by forwarding if we are reading ahead to the sync command.
2. When switching from stand-alone to renderer clock we assume they are
exactly at the same position. This is true in theory, but in practise there
may be small differences due to the different natures of these clocks. To
prevent jumping backwards in time, we can temporarily stop the stand-alone
clock and only switch once the renderer clock reached the same position.
PiperOrigin-RevId: 260690468
Both periods are rarely updated in the same iteration. If they are, advancing
the reading period first seems more logical and also more efficient as it may
avoid one extra doSomeWork iteration.
PiperOrigin-RevId: 260463735
When using speed adjustment it was possible for playback to get stuck at a
period transition when the channel count changed: SonicAudioProcessor would be
drained at the point of the period transition in preparation for creating a new
AudioTrack with the new channel count, but during draining the incorrect (new)
channel count was used to calculate the output buffer size for pending data from
Sonic. This meant that, for example, if the channel count changed from stereo to
mono we could have an output buffer size that stored an non-integer number of
audio frames, and in turn this would cause writing to the AudioTrack to get
stuck as the AudioTrack would prevent writing a partial audio frame.
Use Sonic's current channel count when draining output to fix the issue.
PiperOrigin-RevId: 260156541
We keep track of the last publicly known playing period to report it as part
of events happening after the period has been released.
In cases where a period briefly becomes the playing one and is released
immediately afterwards, we currently don't save it as the "last known playing
one". Improve that by saving an explicit reference.
Issue:#5407
PiperOrigin-RevId: 259737218
Creating a period in MaskingMediaSource may result in delayed event reporting
depending on when the actual period gets created. To avoid event reporting
inaccuracies, report the mediaPeriodCreated and mediaPeriodReleased events
directly.
Issue:#5407
PiperOrigin-RevId: 259737170
This changes the logic in the following ways:
- If no preferred language is matched, prefer better scores for the selected
audio language.
- If a preferred language is matched, always prefer the better match
irrespective of default or forced flags.
- If a preferred language score and the isForced flag is the same, prefer
tracks with a better selected audio language match.
PiperOrigin-RevId: 259707430
Some variables were defined although they are the default and other things
were set-up in a non-sensible way, e.g. asserting that audio is selected
although no audio renderer is available, or using unset duration for
everything.
PiperOrigin-RevId: 259532782
PlaybackInfo changes are one of the last ones not masked and reported in the same
way as all other changes.
The main change to support this is to also mask the parameters set in
DefaultAudioSink.
PiperOrigin-RevId: 258787744
1. Using the Locale on API<21 doesn't make any sense because it's a no-op
anyway. Slightly restructured the code to avoid that.
2. API<21 often reports languages with non-standard underscores instead of
dashes. Normalize that too.
3. Some invalid language tags on API>21 get normalized to "und". Use original
tag in such a case.
Issue:#6153
PiperOrigin-RevId: 258773463
2-letter codes (ISO 639-1) are the standard Android normalization and thus we
should prefer them to 3-letter codes (although both are technically allowed
according the BCP47).
This helps in two ways:
1. It simplifies app interaction with our normalized language codes as the
Locale class makes it easy to convert a 2-letter to a 3-letter code but
not the other way round.
2. It better normalizes codes on API<21 where we previously had issues with
language+country codes (see tests).
3. It allows us to normalize both ISO 639-2/T and ISO 639-2/B codes to the same
language.
PiperOrigin-RevId: 258729728
If we use the default start position, we currently resolve it immediately
even if we need to play an ad first, and later try to project forward again
if we believe that the default start position should be used.
This causes problems if a specific start position is set and the later
projection after the preroll ad shouldn't take place.
The problem is solved by keeping the content position as TIME_UNSET (= default
position) if an ad needs to be played first. The content after the ad can
then be resolved to its current default position if needed.
PiperOrigin-RevId: 258583948
These methods helps to indicate that a media source isn't used to create new
periods in the immediate term and thus limited resources can be released.
PiperOrigin-RevId: 258373069
It's easy to forget to forward methods when using basic wrapping. For example,
ExtractorMediaSource.addEventListener is currently a no-op because it's not
forwarded.
PiperOrigin-RevId: 257757556
This is a temporary workaround until we have migrated all MediaSources uses.
This change avoids having to migrate all uses of MediaSources immediately.
PiperOrigin-RevId: 257459138
- Remove manifest argument from callbacks of Player.EventListener and
SourceInfoRefreshListener. Instead make it accessible through
Player.getCurrentManifest() and Timeline.Window.manifest.
- Fix all MediaSource implementation to include the manifest in the
Timeline instead of passing it to the SourceInfoRefreshListener.
- Refactor ExoPlayerTestRunner, FakeTimeline, FakeMediaSource to
reflect these changes and make tests pass.
PiperOrigin-RevId: 257359662
Sending MESSAGE_PREPARE_SOURCE should happen last in the constructor.
It was previously happening before initialization finished (and in
particular before pendingMediaPeriods was instantiated).
Issue: #6146
PiperOrigin-RevId: 257158275
We currently handle most the control code logic after handling special
characters. This includes filtering out repeated control codes and checking
for the correct channel. As the special character sets are control codes as well,
these checks should happen before parsing the characters.
Issue:#6133
PiperOrigin-RevId: 256993672
- Explicitly specify HTTP_METHOD_POST (previously this was
implicit as a result of the body data being non-null)
- Use null when there's no body data (it's converted to
null inside of the DataSpec constructor anyway)
PiperOrigin-RevId: 256573384
Currently, we sometimes apply new playback parameters directly and sometimes
through the list of playbackParameterCheckpoints. Only when using the checkpoints,
we also reset the offset and corresponding position for speedup position
calculation. However, these offsets need to be changed in all cases to prevent
calculation errors during speedup calculation[1].
This change channels all playback parameters changes through the checkpoints to
ensure the offsets get updated accordingly. This fixes an issue introduced in
31911ca54a.
[1] - The speed up is calculated using the ratio of input and output bytes in
SonicAudioProcessor.scaleDurationForSpeedUp. Whenever we set new playback
parameters to the audio processor these two counts are reset. If we don't reset
the offsets too, the scaled timestamp can be a large value compared to the input
and output bytes causing massive inaccuracies (like the +20 seconds in the
linked issue).
Issue:#6117
PiperOrigin-RevId: 256533780
The masking logic for unprepared MediaSources is currently part of
ConcatanatingMediaSource. Moving it to its own class nicely separates the
code responsibilities and allows reuse.
PiperOrigin-RevId: 256360904
1. Only output video starting from a keyframe
2. When calculating the timestamp offset to adjust live streams to start
at t=0, use the timestamp of the first tag from which a sample is actually
output, rather than just the first audio/video tag. The test streams in
the referenced GitHub issue start with a video tag whose packet type is
AVC_PACKET_TYPE_SEQUENCE_HEADER (i.e. does not contain a sample) and whose
timestamp is set to 0 (i.e. isn't set). The timestamp is set correctly on
tags that from which a sample is actually output.
Issue: #6111
PiperOrigin-RevId: 256147747
The total window and period count, as well as the period offset for each holder
are not actually needed and can be removed.
Also added a TODO to remove two other variables if possible.
PiperOrigin-RevId: 255945584
We are currently queuing periods in a way such that the new start position
lines up with the end of the previous period (to ensure continuous playback).
However, if the start position of the new period is larger than the total of
all previously played period durations, we may end up with negative renderer
timestamps when seeking back to the beginning of this new period. Negative
timestamps should be avoided as most decoders have problems handling them
correctly.
This change forces a renderer reset if we detect such a seek to a negative
renderer time and also resets the renderer offset to 0 every time all
renderers are disabled, as this is the only time where we can savely change
the offset of an existing media period.
Also, if playback starts with an ad, we choose the content position as
renderer offset to prevent the whole issue from occurring for the seek-behind-
midroll case.
Issue:#6009
Issue:#5323
PiperOrigin-RevId: 253790054
In some edge cases the renderer position may be slightly ahead of the
buffered position and the total buffered duration is thus negative. We already
filter that in ExoPlayerImpl for the publicly accessible value. However, we
forward the unfiltered value to other components like the LoadControl, which
may be confusing.
Issue:#6015
PiperOrigin-RevId: 253780460
This permission has normal access right and can't be revoked by the user.
However, an app can choose to revoke it when using ExoPlayer, e.g. if
no network is required and the app doesn't want to list this permission.
Support this use case by gracefully catching the exception in the relevant
places.
Issue:#6019
PiperOrigin-RevId: 253759332
We currently report MediaCodec exceptions as unexpected exceptions instead of
as renderer error. All such exceptions are now wrapped in a new DecoderException
to allow adding more details to the exception.
PiperOrigin-RevId: 252054486
It's only thrown in an edge case on API level 20 and below. If it
is thrown it causes playback failure when playback could succeed,
by throwing up through configureCodec.
It seems better just to catch the exception and have the codec be
configured using the format's own width and height.
PiperOrigin-RevId: 251745539
We currently don't display the last frame because the seek time is behind the
last frame's timestamps and it's thus marked as decodeOnly.
This case can be detected by checking whether all data sent to the codec is
marked as decodeOnly at the time we read the end of stream signal. If so, we
can re-enable the last frame. This should work for almost all cases because the
end-of-stream signal is read in the same feedInputBuffer loop as the last
frame and we therefore haven't released the last frame buffer yet.
Issue:#2568
PiperOrigin-RevId: 251425870
Using parallel adaptation for Formats without bitrate information currently
causes an exception. Handle this gracefully and also cases where all formats
have the same bitrate.
Issue:#5971
PiperOrigin-RevId: 250682127
Setting the requested encoding in all cases ensures we receive the relevant
response headers indicating whether gzip was used. Doing that allows to
detect the content length in cases where gzip was requested, but the server
replied with uncompressed content.
PiperOrigin-RevId: 250660890
cache() opens all connections with unset length to avoid position errors.
This makes more data then needed to be downloading by the underlying
network stack.
This fix makes makes it open connections for only required length.
Issue:#5927
PiperOrigin-RevId: 250546175
"Write case, lock not available" was a bit confusing. When the
content is not cached and the lock is held, it's neither a read
or a write case. It's a "can't do anything" case. When blocking,
it may subsequently turn into either a read or a write.
PiperOrigin-RevId: 250530722
The former is deprecated and replaced by the latter in Mockito 2. However, there is a
functional difference: ArgumentMatchers will reject `null` and check the type
if the matcher specified a type (e.g. `any(Class)` or `anyInt()`). `any()` will
remain to accept anything.
PiperOrigin-RevId: 250458607
Removes the need for duplicate calls to SampleQueue#read when
implementing DecryptionResources acquisition in the MediaSources.
PiperOrigin-RevId: 250298175
The only known use case for contentTypePredicate is to catch
the case when a paywall web page is returned via a DataSource,
rather than the data that was being requested. These days streaming
providers should be using HTTPS, where this problem does not exist.
Devices have also gotten a lot better at showing their own
notifications when paywalls are detected, which largely mitigates
the need for the app to show a more optimal error message or
redirect the user to a browser.
It therefore makes sense to deprioritize this feature. In
particular by removing the arg from constructors, where nearly
all applications are probably passing null.
PiperOrigin-RevId: 249634594
This prevents further unexpected updates if the MediaSource happens to
finish its preparation at a later point.
Issue:#5915
PiperOrigin-RevId: 249439246
We are currently defaulting to targetSdk=1 as no targetSdk is specified. Only
tests which explicitly ask for another SDK use another test SDK. With the
versioned manifest, all tests run using the targetSDK by default.
PiperOrigin-RevId: 249060796
If a PlayerMessage throws an exception, it is currently not deleted from the
list of pending messages. This may be problematic as the list of pending
messages is kept when the player is retried without reset and the message is
sent again in such a case.
PiperOrigin-RevId: 247414494
Adding an explicit option to clear all downloads prevents repeated database
access in a loop when trying to delete all downloads.
However, we still create an arbitrary number of parallel Task threads for this
and seperate callbacks for each download.
PiperOrigin-RevId: 247234181
1. A content session after an ad has been played was not re-marked as active,
leading to new ad session being marked as active too early.
2. Switching from content to post-roll ended the content session because
the return value of getAdGroupTimeUs of C.TIME_END_OF_SOURCE was not
handled. Using the nextAdGroupIndex instead.
PiperOrigin-RevId: 246977327
As justification for why we should not have this type of logging,
it would scale up to about 13K LOC, 1800 Strings, and 36K (after
pro-guarding - in the case of the demo app) if we did it through
the whole code base*. It makes the code messier to read, and in
most cases doesn't add significant value.
Note: I left the Scheduler logging because it logs interactions
with some awkward library components outside of ExoPlayer, so is
perhaps a bit more justified.
* This is a bit unfair since realistically we wouldn't ever add
lots of logging into trivial classes. But I think it is fair
to say that the deltas would be non-negligible.
PiperOrigin-RevId: 246181421
- Removed DownloadInternal and its sometimes-out-of-sync
duplicate state
- Fixed downloads being in STOPPED rather than QUEUED state
when the manager is paused
- Fixed setMaxParallelDownloads to start/stop downloads if
necessary when the value changes
- Fixed isWaitingForRequirements
PiperOrigin-RevId: 246164845
They behave identically, and the old names are being removed.
Open-source note: The new methods are available in Truth as of version 0.44.
END_PUBLIC
More information:
go/issameas-lsc
Tested:
TAP --sample ran all affected tests and none failed
http://test/OCL:246024032:BASE:246042619:1556672975894:513e7746
PiperOrigin-RevId: 246101315
This resolves some naming confusion that previously existed
as a result of DownloadThread also being used for removals.
Some related variables (e.g. activeDownloadCount) would refer
to both download and removal tasks, whilst others
(e.g. maxParallelDownloads) would refer only to downloads.
This change renames those that refer to both to use "task"
terminology.
This change also includes minor test edits.
PiperOrigin-RevId: 245913671
[Problem]
There are 3 services / modes transported on line 21:
- Captioning
- TEXT (generally not program related)
- XDS (eXtended Data Services)
Bytes belonging to the unsupported modes are interleaved with the
bytes of the captioning mode.
See Chapter 7, Chapter 8.5 and Chapter 8.6 of the CEA608 Standard for
more details.
[Solution]
Drop all bytes belonging to unsupported modes.
[Test]
- All streams containing only captioning services should not be influenced
- Test all 4 CEA 608 channels with live over-the-air content and
using all available TEXT and XDS streams.
There are no logic changes here. It's just moving code around and removing
the "internal" part of names where no longer required.
PiperOrigin-RevId: 245407238
This ensures we keep the loading period in sync with the the playing period in
PlybackInfo, when the latter changes to something new.
PiperOrigin-RevId: 244838123
Experiments show this is beneficial for rebuffers with only minor impact
on battery usage.
Configurations which explicitly set a minimum buffer duration are unaffected.
Issue:#2083
PiperOrigin-RevId: 244823642
Before this change we'd release the audio track and create a new one as soon
as audio processors had drained when reconfiguring.
Fix this behavior by stop()ing the AudioTrack to play out all written data.
Issue: #2446
PiperOrigin-RevId: 244812402
- We had buildAddRequest and sendNewDownload. Converged to
buildAddDownload and sendAddDownload.
- Also fixed a few more inconsistencies, and brought the
action constants into line as well.
PiperOrigin-RevId: 244274041
- Listener based reporting of progress allows the content length
to be persisted into the download index (and notified via a
download state change) as soon as it's available.
- Moved contentLength back into Download proper. It should only
ever change once, so I'm not sure it belongs in the mutable part
of Download.
- Made a DownloadProgress class, for naming sanity.
PiperOrigin-RevId: 244242487
1. customCacheKey for DASH/HLS/SS is now asserted against
in DownloadRequest
2. Merging of event delivery in DownloadManager is very
tricky to get right and probably not a good idea
PiperOrigin-RevId: 244048392
Currently SimpleCache will touch cache spans whenever it reads
from them. With legacy SimpleCache setups this involves a potentially
expensive file rename. With new SimpleCache setups it involves
a more efficient but still non-free database write.
For offline use cases, and more generally any use case where the
eviction policy doesn't use last access timestamps, touching is
not useful. This change allows the evictor to specify whether it
needs cache spans to be touched or not. SimpleCache will only touch
spans if the evictor requires it.
Note: There is a potential change in behavior in cases where a
cache uses an evictor that doesn't need cache spans to be touched,
but then later switches to an evictor that does. The new evictor
may temporarily make sub-optimal eviction decisions as a result.
I think this is a very fair trade-off, since this scenario is
unlikely to occur much, if at all, in practice, and even if it
does occur the result isn't that bad.
PiperOrigin-RevId: 244005682
One goal we forgot about a little bit was to allow applications
to provide their own index implementation. This requires the
writable side to also be defined by an interface.
PiperOrigin-RevId: 243979660
ImaAdsLoader gets the player position after the app releases
the player to support resuming ads at their current position
if the same ads loader is reused.
PiperOrigin-RevId: 243969916
ShadowLooper -> ShadowLegacyLooper
ShadowRealisticLooper -> ShadowPausedLooper
ShadowBaseLooper -> ShadowLooper
And all public methods from ShadowLegacyLooper get pushed up to ShadowLooper
Pull Request: https://github.com/robolectric/robolectric/pull/4868
Copybara: OK
Also adjust Google3 tests using custom looper shadows where necessary.
Convert exoplayer to paused looper to eliminate reliance on custom shadows
PiperOrigin-RevId: 243839311
The removed condition only applies when prepare fails and no timeline was or
is known. We should keep a pending seek position in such a case. The internal
player does the same thing already.
PiperOrigin-RevId: 243819466
- Expose constructors that take DatabaseProvider. Deprecate those
that do not.
- Expose Cache.getUid. This will likely be used for naming of the
tables accessed by DefaultDownloadIndex .
PiperOrigin-RevId: 243637786
- Allows enforcing immutability, which in a future CL will allow
avoiding allocating a new array/list on every call.
- Also some left over doc cleanup from the DownloadState rename.
PiperOrigin-RevId: 243627352
The old domain automatically forwards to the new one. For consistency, change
all doc and code references regardless.
Also adds GitHub CNAME config file which configures our page for the custom
domain.
PiperOrigin-RevId: 243592110
handleSourceInfoRefreshed checks for various conditions which may trigger a
change in position. In all cases, we need to resolve the new position for ads,
and if the corresponding MediaPeriods already exist, perform the seek to the new
position.
This change simplified the code by
1. Moving all conditions in a single if-else structure which just determines
the new playback position. This makes it easier to read and to follow.
2. Doing the subsequent seek and position update in one final step to remove
duplicated code.
As a side effect, it also improves some edge cases. For example when skipping
an ad to an already prebuffered period, we now properly update the existing
prebuffered period.
PiperOrigin-RevId: 243588014
- Make a best effort to avoid posting MSG_DOWNLOAD_THREAD_STOPPED
if the internal thread has already quit. Doing so is harmless,
but causes an error in Logcat. We used to generate this warning
quite a bit in ExoPlayerImplInternal as well, and we got quite
a few issues filed about it, so best to avoid it if possible.
- Null out the back reference DownloadThread holds to its manager
on release. This avoids a potential issue where a download thread
can prevent GC of its manager if it doesn't cancel quickly.
There's similar logic (with a similar comment) in Loader.LoadTask.
PiperOrigin-RevId: 243365143