This option marks streams as final such that renderers play them out
completely, then waits until this happened, and then sets the player
to paused. After that, the player can continue to read the next period
to quickly resume playback if needed.
PiperOrigin-RevId: 298824745
Update it to allow any listener class to be registered (and thus
require the caller of dispatch() to provide the type of listener
to call).
Maintain MediaSourceEventListener.EventDispatcher as a sub-class
for now so that all existing references continue to work. This
avoids creating a huge diff in one CL. The intention is to in-line
these incrementally.
This is pre-work for issue:#6765
PiperOrigin-RevId: 298818198
The default Robolectric Looper simulation mode is changing to PAUSED from LEGACY.
The following tests fail in this new mode, and are thus being defaulted to LEGACY.
For more details see go/robolectric-legacy-looper-mode-lsc
Cleanup change automatically generated by error-prone refactoring
//third_party/android/androidx_test/tools/errorprone/java/androidx/test/tools/errorprone:LegacyLooperModeConverter_refactoring
Tested:
TAP train for global presubmit queue
http://test/OCL:297627974:BASE:298600828:1583273401491:7d94dbaa
PiperOrigin-RevId: 298809656
DashMediaSource is created with Manifest data and streamKeys can be empty given that streamKeys are only created out of MediaItem inside DashMediaSource, and this particular implementation don't extract them out of MediaItem properties.
Tested=Verified playback works.
PiperOrigin-RevId: 298550021
This change adds the createMediaSource(MediaItem mediaItem) method to the MediaSourceFactory interface. It doesn't deprecate createMediaSource(Uri uri) to keep the cl smaller. Deprecation and removing calls to the deprecated method from within the library and extension follow in a separate CL.
PiperOrigin-RevId: 298352442
The test had two problems:
1. It posts messages using a Handler and we need to idle the main looper
to actually deliver this message.
2. SimpleDecoder uses a background thread that is not within our control
from the test. Ensure the decoding happens after we queue input buffers
by using a lock.
PiperOrigin-RevId: 298300175
This is one step toward following the google3's test naming convention.
See go/java-testing/getting_started#basic-test-template for details
why prefix test isn't necessary.
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/' {}
and then manually modified following tests where test method names conflict with test target.
- VorbisUtilTest
- VorbisReaderTest
- UtilTest
- DownloadManagerDashTest
- DefaultOggSeekerTest
- OggPageHeaderTest
- HlsMasterPlaylistParserTest
PiperOrigin-RevId: 298074653
We should only ignore seek to the current position if we are
currently READY or BUFFERING. Also, pending initial seek positions
should only be saved while we have an empty timeline, independent of
the player state.
Issue:#6886
PiperOrigin-RevId: 297813854
This is more accurate since it's just a placeholder and none of the
values is provided by the media.
It also allows to fix a problem in ClippingMediaSource where we
couldn't detect a clipping error because we didn't know if the
timeline is a placeholder or not.
Issue:#5924
PiperOrigin-RevId: 297813606
When a new Timeline arrives in the Player, we check whether we can keep
existing MediaPeriods. This check currently involves a condition that
checks if the MediaPeriod is already prepared. The only reason we do
that is to avoid calling MediaPeriod.seekToUs, which is not allowed
on an unprepared MediaPeriod.
It's better to keep the MediaPeriod to prevent restarting the
preparation process. The prepration check can move further down to the
place right before we would call seekToUs.
PiperOrigin-RevId: 297812584
AnalyticsCollector keeps a list of existing MediaPeriodInfo that need
to be updated to new Timelines when they arrive. This already
happens in all cases except that the playingMediaPeriod wasn't updated
when it didn't change during the timeline update.
PiperOrigin-RevId: 297812038
The positions were interchangeably used with window and period
positions. This change more clearly ensures that all positions in the
AdPlaybackState are based on periods and that we use the right adjustments
for all usages.
PiperOrigin-RevId: 297811633
This removes noisy data from the dump files and allows updating less
dump files if a format field is added, removed or updated.
PiperOrigin-RevId: 297617138
Parallel asynchronous calls to MediaCodec.queueSecureInputBuffer() may
produce garbled video on some platforms. This workaround synchronizes
calls to MediaCodec.queueSecureInputBuffer() so that only one call is
in flight.
PiperOrigin-RevId: 297601037
This change adds the callback onSkipSilenceEnabledChange to the AudioListener and calls it when changed by the user by calling setPlaybackParameters, or when changed internally by the DefaultAudioSink if the parameters are not applicable. It needs to be plumped through AudioSink, AudioRenderer to SEP which eventually calls the AudioListener.
No changes to the Player interface so far. The getter of skipSilenceEnabled is added to SimpleExoPlayer for completeness, but not yet to the Player interface. The setter is not yet exposed, but implemented as a private method for implementation reasons.
PiperOrigin-RevId: 297590291
DefaultLoadControl applies the same min buffer duration to audio
and video. By default, min buffer is set equal to max buffer (50 seconds).
PiperOrigin-RevId: 297324489
Note: The dump files will need updating again when the extractors
are modified to only set the appropriate bitrate. Enhancing the
test first is nice, because it means that in subsequent CLs the
dump file updates can be used to quickly see what's changed in
the output.
PiperOrigin-RevId: 297188367
- Avoid having ExtractorHolder expose the underlying extractor.
- Make ProgressiveMP inject a DataSource instead of a DefaultExtractor.
This CL should introduce no functional changes.
PiperOrigin-RevId: 296944788
This change deprecates PlaybackParameter in AudioSink and splits it into playbackSpeed and skipSilenceEnabled. These properties are set separately in a future CL. The playback speed will be set through the MediaClock, while skipSilenceEnabled will be set by sending a message to the audio renderer.
PiperOrigin-RevId: 296457043
- Deprecate old Format.createXXX methods
- Deprecate most Format.copyXXX methods
- Stop using deprecated Format.copyXXX methods in the library
Note: Replacing library usages of Format.createXXX method
will be done in follow up CLs. These changes aren't purely
mechanical because we need to decide which out of peakBitrate
and averageBitrate to set in each case where currently a
single bitrate is provided.
Issue: #2863
PiperOrigin-RevId: 296450935
It's not clear why we're currently outputting the format in both init()
and consume() - it seems likely that this was accidentally introduced
in <unknown commit>
when we started outputting the format in consume() but didn't remove it
from init().
The SCTE-35 TsExtractorTest doesn't pass with the current code because
when it seeks back to the beginning of the file init() is not called
again so the second pass through only sees one sample (and
ExtractorAsserts checks that seeking back to 0 produces the same output
as reading the file from the beginning).
I generated the SCTE-35 sample using TSDuck's tsp command:
$ tsp --add-input-stuffing 1/10 \
-I file testdata/src/test/assets/ts/sample.ts \
-P pmt --service 1 --add-programinfo-id 0x43554549 --add-pid 600/0x86 \
-P spliceinject --service 1 --files scte_35.xml --wait-first-batch \
-P filter --negate --pid 0x1FFF \
-O file testdata/src/test/assets/ts/sample_scte35.ts
This was adapted from the instructions in section 5.2.24.1 of the TSDuck
user manual: https://tsduck.io/download/docs/tsduck.pdf
PiperOrigin-RevId: 296217084
Not important, but when overriding a method that can return null,
it seems preferable to put @Override first, followed by what it's
overriding (which includes the @Nullable).
Also remove explicit @NonNull use in the core library. @NonNull is
propagated by default, so this is redundant.
PiperOrigin-RevId: 296188379
This is one step toward following the google3's test naming convention.
See go/java-testing/getting_started#basic-test-template for details
why prefix test isn't necessary.
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: 296169886
When copying CryptoInfo for asynchronous input buffer queueing,
re-use the destination CryptoInfo's arrays to avoid re-allocating
memory.
PiperOrigin-RevId: 295706771
Note on UnknownNull: Where there exists a generically typed
base class and both null and non-null types are permitted,
we need to clear the default non-null that's otherwise
propagated everywhere. This then lets the nullness of the
type work properly.
PiperOrigin-RevId: 295582444
CryptoInfo.iv length is always 16. When the actual initialization vector
is shorter, zero out the trailing bytes.
Issue: #6982
PiperOrigin-RevId: 295575845
Previously, the input buffer accessUnit count
was passed as the output of the audio processors
which did not make sense as the processors can
split buffers.
This patch passes the access unit count through a
member variable.
PiperOrigin-RevId: 295572577
This is closer to how our actual renderers look like and allows tests
to use a similar logic to show/suppress the first frame in follow-up changes.
PiperOrigin-RevId: 295557548
We will eventually remove the workaround from ExoPlayerImplInternal
added in
b84bde0252
and replace it by an error that gets thrown if the LoadControl behaves
badly.
PiperOrigin-RevId: 295556131
Previously that was implicit, it was the passthrough dance:
- MimeTypes.getEncoding(inputFormat) did not
implement RAW MIME, so it was returning INVALID_ENCODING for PCM
- and allowPassthrough was returning
MimeTypes.getEncoding() != INVALID_ENCODING
- which was setting codecInfo.passthrough, and passthroughEnabled.
Thus Util.isEncodingPcm(encoding) is the opposite of
(MimeTypes.getEncoding(inputFormat) != C.ENCODING_INVALID)
This was rather implicit and brittle as anyone
could add support for audio/RAW in
MimeTypes.getEncoding and break PCM playback.
As a result make it explicit that allowPassthrough
must always return false in PCM.
PiperOrigin-RevId: 295144013
Modify TrackOutput.sampleData() to accept SampleDataReader instead of ExtractorInput. SampleDataReader supports only read and skip calls, which all sampleData() implementations already restrict themselves to.
PiperOrigin-RevId: 294905155
Currently only one access unit can be written per
buffer write. This has been found to be power
inefficient in an offload situation.
#exo-offload
PiperOrigin-RevId: 294886188
This information isn't easily available to the player at the moment (or it
would need to revaluate this every time), so add it to MediaPeriodInfo similar
to the existing isLastInTimelinePeriod.
The player needs to know whether a MediaPeriod is the last in its Timeline
window if we want to add an option to pause at the end of a window.
PiperOrigin-RevId: 294877628
Add fields in DecoderCounters for computing the average video frame
processing offset.
The MediaCodecVideoRenderer reports the video frame processing offset
and the demo app presents it on the debug information.
PiperOrigin-RevId: 294677878
The transition in EPII happens based on the duration of the periods, not
the windows. So use this duration in case they are not the same.
Also make sure to send the message at duration-1 because the playback position
at the duration is technically already the first position in the next item.
PiperOrigin-RevId: 294669335
This simplifies sending messages to the end of a stream. This was
already possible, but users needed to wait until the duration is known
before sending the message. This duration resolution can happen as part of the message position resolution.
PiperOrigin-RevId: 294626984
Language is already applicable to image formats as well.
It can also apply to video formats. For example when the
video contains burnt in subtitles. Also, some animation
studios produce multiple variants of animations, in which
text within the scene itself (e.g., a signpost) is
replaced to be language specific.
PiperOrigin-RevId: 294500227
- Replace tests specific to HTTP request headers with tests that
more generally test constructor correctness.
- Add test specifically around the constructor that infers the
HTTP method from postBody, since that's a non-trivial bit of
constructor logic.
Note: In general, I'm not sure this type of test (i.e., testing a
bit of trivial copying through a constructor) is worth the cost
of writing and maintaining them. That said, checking the new
uriPositionOffset is calculated correctly is non-trivial, as is
the HTTP method inference, so keeping them for now.
PiperOrigin-RevId: 294488684
This is a preliminary step toward adding a DataSpec.Builder,
which is needed for sanity when adding DataSpec.customData.
The existing absoluteStreamPosition field is very error prone,
because anyone using a Builder to adjust the request position
will need to remember to adjust two values:
dataSpec
.buildUpon()
.setAbsoluteStreamPosition(x)
.setPosition(x)
.build();
Furthermore, the difference between position and
absoluteStreamPosition is irrelevant in nearly all cases. In
the core library, the difference is only relevant when initializing
AES encryption/decryption to write/read cache files.
Replacing absoluteStreamPosition with uriPositionOffset will
simplify the code block above to:
dataSpec
.buildUpon()
.setPosition(x)
.build();
PiperOrigin-RevId: 294485644
Currently, the subset of audio tracks for adaptation is selected
purely based on the size of the subset in the track group, completely
ignoring the previously selected best individual track.
This change ignores all tracks with a different configuration than the
previously selected best track.
PiperOrigin-RevId: 294231806
While the window in which a message or a seek position is resolved is
still a placeholder, we need to re-resolve the position using the
user intent (i.e. the window position) when the timeline updates.
PiperOrigin-RevId: 293346360
The period in this method is most likely prepopulated correctly, but
this assumption is very error-prone and we should populate it locally.
PiperOrigin-RevId: 293345873
This allows to simulate samples in a stream more accurately
particularly when streams are prepared at a non-zero position and
issuing a sample with position=0 is not expected.
Also makes seek more realistic by also issuing one sample again.
PiperOrigin-RevId: 293344081
Once we receive an update from a masked source, we first start the
preparation of an already pending period, and only then notify the
player of the new timeline. If the period prepares immediately inline,
the MediaPeriod.onPrepared callback arrives before the
onPlaylistUpdateRequested call in the Player. THis is the wrong order
and causes issues when the player tries to lookup information in the
timeline that doesn't exist yet.
This change fixes preroll playbacks before live streams.
PiperOrigin-RevId: 293340031
The functional change is to set the bitrate fields to Format.NO_VALUE
in the case that they're non-positive in the header data. Else it's
very easy to to take the fields and copy them directly into Format as
incorrect values.
Issue #2863
PiperOrigin-RevId: 292920141
This change deprecates Player.onPlayerStateChanged(boolean pwr, int state). It removes deprecation for trivial cases. I'll remove other deprecated usages (mostly in ui module) in follow-up CLs to not bloat this CL.
PiperOrigin-RevId: 292917872
This condition is trying to detect when it might be necessary
to switch from a non-secure to a secure codec. This is not
possible if the DRM session is unchanged, unless a different
codec is required for some other reason (e.g., H264 -> H265),
which is anyway handled by canKeepCodec below.
PiperOrigin-RevId: 292909126
*** Original commit ***
Rollback of 3c56b113e4
*** Original commit ***
Rollback of d48dc4c159
*** Original commit ***
Move getting-stuck-prevention into DefaultLoadControl.
We recently added code that prevents getting stuck if the buffer is low and
the LoadControl refuses to continue loading (b84bde0252).
Move this logic...
***
PiperOrigin-RevId: 292457964
Passing EXT-X-KEY DrmInitData through the FragmentedMp4Extractor
doesn't work for streams with key rotation, because an extractor
instance is used for multiple segments, but is only passed the
EXT-X-KEY DrmInitData corresponding to the first segment.
This change removes passing DrmInitData through the extractor,
and instead passes it via FormatAdjustingSampleQueue. This is
in-line with how manifest DrmInitData is handled during DASH
playbacks.
Issue: #6903
PiperOrigin-RevId: 292323429
This is a nice-regardless improvement to SampleQueue, which will
likely to used to fix the referenced issue. It makes it possible
for SampleQueue subclasses to support dynamic changes to format
adjustment in a non-hacky way.
Issue: #6903
PiperOrigin-RevId: 292314720
Fix outline style subtitle
When a ForegroundColorSpan changes the foreground color, it is also applied
to the outline painter. In order to keep the correct color, one needs to
filter out theses span. We do this with a new cue that is our text source
for the specific edgeLayout.
Take care to only apply background color once
Test: Manual check - Subtitle view can show custom color subtitles from specific Subtitle
Renderer and outline is shown correctly using user defined color.
Calling setViewType with the same view type as the
subtitleView is using would throw InvalidArgumentException
instead of being a noop.
PiperOrigin-RevId: 291937202
We currently have 3 states, but the NOT_SET state isn't needed
anymore. We can therefore replace the IntDef by a simple boolean.
PiperOrigin-RevId: 291926049
We currently apply new parameter checkpoints from an absolute media
time and then substract the current media start time again to retrieve
the media time offset for this playback parameter checkpoint.
However, the media start time may change when unexpected discontinuities
happen (the start time doesn't actually change, but we change it to
correct for this discontinuity). This then invalidates the absolute
media time in the playback parameter checkpoints (which should have been
corrected as well).
Avoid this problem by also only applying the new start position
from the checkpoint. We don't have to save the start position anymore
because it will cancel itself out.
Also add some documentation and code clarification for improved
readability.
PiperOrigin-RevId: 291923069
SubtitleView now becomes a ViewGroup that owns a SubtitleTextView. It
handles some common styling defaults, but delegates the underlying
values down into SubtitleTextView through the SubtitleView.Output
interface.
When I add a SubtitleWebView this will also be a ViewGroup containing
a WebView and will implement SubtitleView.Output and convert Cue styling
into HTML & CSS.
PiperOrigin-RevId: 291903294
It doesn't seem worth keeping the cap, since the device
will presumably stop receiving major version updates at
some point anyway.
Issue: #6899
PiperOrigin-RevId: 291899439
This seeker is only seeking to frames that have already been read by the
extractor for playback. Seeking to not-yet-read frames will be
implemented in another change.
Issue: #6787
PiperOrigin-RevId: 291888899
We currently only keep the requested next content start position while
we are playing ads. However, we should also keep at least before a content
period is fully prepared to not loose the information about the user intent.
PiperOrigin-RevId: 291705752
There are existing bugs that need this flag to know whether the
current information in the window is still a placeholder or can
already be relied on for further calculation.
This flag will probably only ever be set in DummyTimeline, so it's
not added to the window.set method to avoid updating all clients.
Issue:#5924
PiperOrigin-RevId: 291705637
It could either live in .util or .extractor, but since it's not needed
outside the extractor package in core (and the FLAC extension), and
FlacStreamMetadataTest uses a FLAC asset, it seems preferable to move it
into the extractor package.
PiperOrigin-RevId: 291372032
CeaUtil depends on TrackOutput so should live in the extractors package.
To avoid having Cea708Decoder depend on extractors, this change also
moves the initialization data building/parsing to CodecSpecificDataUtil.
PiperOrigin-RevId: 291348317
Using @Test(expected=...) is discouraged, since the test will pass if
any statement in the test method throws the expected exception.
PiperOrigin-RevId: 291338224
Since we have the Playlist layer on top, it's always guaranteed that a
new playlist item has a new uid. So we can just keep the old one in all
cases and don't have to be careful to delete it. The deletion was necessary
previously in case multiple MediaSources use the same uids.
PiperOrigin-RevId: 291152349
Move Cea708InitializationData functionality into CeaUtil and delete the
class.
Move CeaUtil to the util package as it needs to be used both in
extraction and decoding.
PiperOrigin-RevId: 291128220
The only remaining use is to provide the initial position for the first media
period in the queue. At this point, the value is always equivalent to
PlaybackInfo.positionUs because they are set together to the same value in
PlaybackInfo.copyWithNewPosition.
PiperOrigin-RevId: 290749294
We have a flag that gets turned on if the current playback position has been
reset, so that messages from this reset position can be triggered. This
mechanism isn't actually depending on the startPositionUs field because it
should always be triggered in the first iteration with the new position.
PiperOrigin-RevId: 290749201
There are a couple of problems with how positions in PlaybackInfo are set at
the moment:
1. PositionUs isn't allowed to be C.TIME_UNSET. This is prevented by always
resolving to the current default position if needed.
2. In some places a window position was used as a period position. Use correct
position resolution procedure.
3. When creating a placeholder position to restart playback, we used the first
period in a window, not the one where the default position is.
4. The start position for ads was in some cases set to 0 without checking
the ad resume position.
PiperOrigin-RevId: 290749042
I needed to use Cue.Builder instead of just SpannableStringBuilder for
the regionOutput values, so I could attach the vertical info where
appropriate (since this is a property of the Cue, not a span).
PiperOrigin-RevId: 290709294
If an exception is thrown between updating the timeline and updating
the position in playbackInfo, the state may be inconsistent.
Exceptions are expected to be thrown while updating the player state
and we should handle such cases in a consistent way.
Similar to how we handle the same situation in seekToInternal,
the state is updated in a final block such that it gets updated to the
latest state even if an error occurs. Moving both the timeline and
position update together also ensures they always stay consistent.
PiperOrigin-RevId: 290624020
This restructure moves all the position resolving code to a static method and
removes the dependency of the MediaPeriodQueue on having an up-to-date timeline.
Both steps allow simplified reasoning about the code as the static method can't change
the state of the player, and there is no risk the queue can use the wrong timeline.
These propoerties allow to fix a bug causing inconsistent states in a follow-up step.
PiperOrigin-RevId: 290616395
It's never assigned or accessed from outside the class.
It was added in
<unknown commit>
then the accessor was removed in
<unknown commit>
PiperOrigin-RevId: 290601998
This makes MPEG audio utilities similar to utilities we have for WAV,
AC-3 etc., and moves them out of the extractor package so that an
extractor module can be split out without needing to have a class in the
extractor package in the common library.
PiperOrigin-RevId: 290595089
*** Original commit ***
Rollback of ff89170b00
*** Original commit ***
Fix some logic in AnalyticsCollector.
All events issued from ExoPlayerImpl (i.e. Player.EventListener events) currently
try to use the media period data from the playing media period as set in the
playback thread queue. This is only correct as long as there no pending masking
operations in ExoPlayerImpl. That's why we currently disable this whenever the timeline
is...
***
PiperOrigin-RevId: 290593700
*** Original commit ***
Fix some logic in AnalyticsCollector.
All events issued from ExoPlayerImpl (i.e. Player.EventListener events) currently
try to use the media period data from the playing media period as set in the
playback thread queue. This is only correct as long as there no pending masking
operations in ExoPlayerImpl. That's why we currently disable this whenever the timeline
is empty or a seek is pending. Since adding all the playlist API methods to the player,
this is no longer the right choice. Moreover,...
***
PiperOrigin-RevId: 290312118
Currently both are updated by separate setters. If an exception is thrown between
the two setters, the state may not be consistent.
Avoid this problem by always setting them together.
PiperOrigin-RevId: 290293600
All events issued from ExoPlayerImpl (i.e. Player.EventListener events) currently
try to use the media period data from the playing media period as set in the
playback thread queue. This is only correct as long as there no pending masking
operations in ExoPlayerImpl. That's why we currently disable this whenever the timeline
is empty or a seek is pending. Since adding all the playlist API methods to the player,
this is no longer the right choice. Moreover, we don't have a definite API that tells
AnalyticsCollector when a playlist API call has been handled (and we don't want to
have one).
We can fix this by always using the current Player position information as the source
of truth (instead of the media period queue). This is definitely more correct and also
works while a masking operation is pending. To fill in the additional information from
the media period queue, we can look up a matching media period. This may not be the
first one in the list if an operation is pending.
The new methods are similar to the previous tryResolveWindowIndex method, but:
1. They are always used (i.e. the current Player state is the main source of truth)
2. They also check the correct ad playback state, that was just ignored previously.
PiperOrigin-RevId: 290284916
Currently seeks are basically ignored. However, it's more realistic to re-queue the
single sample if the seek is to position 0.
PiperOrigin-RevId: 290273564
*** Original commit ***
Rollback of d48dc4c159
*** Original commit ***
Move getting-stuck-prevention into DefaultLoadControl.
We recently added code that prevents getting stuck if the buffer is low and
the LoadControl refuses to continue loading (b84bde0252).
Move this logic into DefaultLoadControl to keep the workaround, and also apply the
maximum buffer size check in bytes if enabled. ExoPlayerImplInternal will now
throw if a...
***
PiperOrigin-RevId: 290273295
- Add additional Listener methods to DownloadManager, to inform of
changes to whether the downloads are paused or waiting for requirements.
- Only schedule the Scheduler if we really are waiting for requirements.
- Only restart the service if we're no longer waiting for requirements,
and if there are queued downloads that will now be restarted.
Previously the service would be restarted whenever the requirements
were met, regardless of whether there was any work to do.
- Restart service if it might be stopping, as well as if it's already
stopped. Also restart service if there's a download state change to a
state for which the service should be started, if.
Issue: #6798
PiperOrigin-RevId: 290270547
First cl towards DefaultMediaSourceFactory (<unknown commit>) does not change the MediaSourceFactory interface except adding @Nullable anotations to setters.
PiperOrigin-RevId: 290269640
Doing so prevent Codec which is a big object with
JNI to be garbage collected.
As the codec can not be hold in the listener, there
is no way to call release, as it must be called on
the same codec.
As a result the release method is also removed.
The downside is that at runtime some callbacks may be
dropped but it should be a short transitive state.
This also simplifies lifecycle of the listener as
the client does not have to know if release needs
to be called or not.
An alternative would have been to hold a weak ref,
but I deemed it too complicated for the
runtime gain.
PiperOrigin-RevId: 290231659
This fixes an issue where a DownloadService implementation
that allows foreground but doesn't provide a scheduler would
not be restarted in the case that it was still in memory but
classed as idle by the platform.
It also speeds up service restart in the case that a
scheduler is provided.
Issue: #6798
PiperOrigin-RevId: 290068960
This method has two use cases:
1. Seeking. Calls are immediately preceded by a call to rewind(), and
the returned value isn't important unless it's ADVANCED_FAILED (i.e.
the caller is only interested in success and failure).
2. Advancing. The return value is important unless it's ADVANCED_FAILED,
in which case the caller wants to treat it as 0.
This change creates separate methods for each use case. The new seekTo
methods automatically rewind and return a boolean. The updated advanceTo
method returns 0 directly in cases where ADVANCED_FAILED was returned.
Arguments that were always hard-coded to true by callers have also been
removed.
This change is a step toward one possible solution for #6155. How we'll
solve that issue is still up for discussion, but this change seems like
one we should make regardless!
Issue: #6155
PiperOrigin-RevId: 290053743
- DownloadManagerHelper now passes all downloads to the
DownloadService when the service is attached (and once
the downloads are known). The service then starts the
foreground notification updater if necessary. This fixes
the ref'd issue.
- Don't call getScheduler() if the service is background
only. This was already documented to be the case on the
DownloadService constructor.
- If the service is started in the foreground on SDK level
26 and higher, satisfy the condition to move the service
to the foreground in onStartCommand rather than in stop().
It's much more obviously correct, and should produce the
same end result.
Issue: #6798
PiperOrigin-RevId: 290050024
Currently the following sequence of events happens at automatic period transitions:
1. Update queue (=release old playing period)
2. Disable unused renderers
3. Enable newly needed renderers
This order requires difficult to follow workarounds in AnalyticsCollector for all
events related to step 2 (disable renderers). The current media period has already
been advanced so can't be used. The current workaround saves the last known playing
media period that was published as part of a PlaybackInfo update in ExoPlayerImpl.
This works in most cases, but is inherently wrong because the published state in
ExoPlayerImpl may be completely unrelated to the updates happening on the playback
thread (e.g. if many other operations are pending).
Simplify and fix this problem by changing the order of the events above:
1. Disable unused renderers.
2. Update queue
3. Enable newly needed renderers.
This way the current playing media period can be used for both renderer disable
and renderer enable events, thus it's correct in all cases and the workaround
in AnalyticsCollector can be removed.
PiperOrigin-RevId: 290037225
Whenever we set the maskingWindowIndex, we also need to set the masking period index
and the masking position. Otherwise it may cause exception when the period index
is used together with the masking timeline.
PiperOrigin-RevId: 290036973
This optimization allows a ChunkSampleStream to output track
formats as soon as they're parsed during an InitializationChunk
load, rather than waiting until after the InitializationChunk
load is completed.
In DASH VOD, a single InitializationChunk typically loads the
moov and sidx atoms in that order. Hence for long form content
where the sidx is a non-trivial size, this may result in the
track formats being output a non-negligible period of time
sooner than was previously the case. This allows downstream
renderers to start codec initialization sooner, potentially
decreasing startup latency.
For a single test stream on a fast & stable network, this
pretty consistently reduced elapsed time until both audio and
video codecs have been initialized from ~0.5s to ~0.3 seconds
on a Galaxy S8. For 5 test runs without and with these patches,
the eventTime logged by EventLogger for the second decoder
init were:
Without (secs): 0.47 0.47 0.45 0.48 0.46
With (secs) : 0.32 0.33 0.34 0.31 0.40
PiperOrigin-RevId: 289845089
The current order of operations means that the Format is only passed
to the chunk's output after the DataSource has been opened. This
means that establishing the network connection and the downstream
renderers initializing their codecs are effectively serialized to
occur one after the other.
In the new order, the Format is passed to the chunk's output before
the DataSource has been opened. This allows the downstream renderers
to initialize their codecs in parallel with the network connection
being established, and hence latency at the start of playback is
reduced.
PiperOrigin-RevId: 289841854
We currently have a currentMediaPeriodId and an activeSessionId that are more
or less tracking the same thing unless the current media period isn't "active" yet.
Simplify this logic by using a single currentSessionId field and the respective
isActive flag of this session. Also move all session creation and activation code in
the same method to make it easier to reason about the code.
This change also fixes a subtle bug where events after a seek to a new window
are not ignored as they should.
PiperOrigin-RevId: 289432181
As discovered whilst investigating #6798, there are cases
where these methods are not correctly. They were added as
convenience methods that could be overridden by concrete
DownloadService implementations, but since they don't work
properly it's preferable to require application code to
listen to their DownloadManager directly instead.
Notes:
- The original proposal to fix#6798 stored the state change
events in memory until they could be delivered. This approach
is not ideal because the events still end up being delivered
later than they should be. We also want to fix the root cause
in a different way that does not require doing this.
- This change does not fix#6798. It's a preparatory step.
Issue: #6798
PiperOrigin-RevId: 289418555
This change makes it clear the SampleQueue doesn't outlive
the wrapping PlayerTrackEmsgHandler, and releases it from
PlayerTrackEmsgHandler.release().
This change is a no-op because calling release() is the
same as reset() in this case (the behavior only differs if
a non-dummy DrmSessionManager is being used).
PiperOrigin-RevId: 289416622
As a result, onMediaChunkLoadStarted gets invoked on the loading thread, and
init on the playback thread, matching the thread access comments.
Issue:#6321
PiperOrigin-RevId: 289167981
Dash live streams require that the client has an accurate wall clock
time and in absence of a UTCTiming element, this is assumed to be the
NTP time.
This change adds NTP time offset resolution for DASH live streams
without such timing elements.
PiperOrigin-RevId: 289098796
Unfortunately devices such as the MI 8 do not provide an alternative
working decoder. Some Vivo devices do provide one though.
PiperOrigin-RevId: 288911897