*** Original commit ***
Rollback of bf5e6c7862
*** Original commit ***
Pass startPositionUs into Renderer.replaceStream
Plumb this down into BaseRenderer.onStreamChanged and use it when
deciding whether to render the first frame of a new period.
***
***
PiperOrigin-RevId: 325251261
*** Original commit ***
Rollback of bf5e6c7862
*** Original commit ***
Pass startPositionUs into Renderer.replaceStream
Plumb this down into BaseRenderer.onStreamChanged and use it when
deciding whether to render the first frame of a new period.
***
***
PiperOrigin-RevId: 325218588
- Attach types for placeholder sessions. If a placeholder session will be
attached and a downstream renderer doesn't know what to do with it, then
this attachment is necessary to correctly determine that the renderer
does not support the track.
- Attach types to sample formats. Without this, if playback fails due to
a CryptoException, the ExoPlaybackException that gets thrown spuriously
indicates that the format's DRM type was not supported.
PiperOrigin-RevId: 325214745
The term "passthrough" was heavily overloaded. For clarity, split most
of its usage to different terms:
* codec "bypass": no MediaCodec is used
* "direct playback": no decoding occurs (but decryption may or may not)
* "decrypt only codec": a MediaCodec used only to decrypt, not decode
* "offload": playback to an offload AudioTrack.
* "passthrough" is now only used in the sense of playing encoded audio
* to a non offload AudioTrack.
PiperOrigin-RevId: 324984612
It seems generally useful to have access to the decoder in
getOutputFormat. We're currently working around lack of access
by using member variables in the concrete audio extension
renderers. In the case of the Ffmpeg extension, holding a
reference to the decoder is preventing it from being garbage
collected when the decoder is released by the base class.
PiperOrigin-RevId: 324799670
After discarding upstream we shouldn't reuse the extractor from the
(newly) last media chunk because the extractor may have been reused
already by the discarded chunks.
Also add an assertion to SampleQueue that prevents the hard-to-detect
failure mode of overlapping sample byte ranges.
Issue: #7690
PiperOrigin-RevId: 324785093
This callback was not notified before, which could theoretically lead to ad
loading timing out. In practice it doesn't currently happen because the timeout
appears to start when the ad cue point is reached, not when loadAd is called.
We notify onLoaded when the ad media period is prepared (for HTML5 the
recommendation is to notify on the HTMLMediaElement 'canplay' event, which this
roughly corresponds to).
PiperOrigin-RevId: 324568407
Issue: #7244 added this feature to HLS. This change is the exact copy
in ChunkSampleStream to add the same support to the other adaptive
formats.
Note that ChunkSampleStream doesn't support slicing, so we can't cancel
a read-from chunk, and we need to prevent reading into an already
canceled chunk load so that the chunk can be automatically discarded
after the cancelation.
Issue: #2848
PiperOrigin-RevId: 324179972
Wrapping MediaCodec ISEs in MediaCodecDecoderException lets us attach
MediaCodecInfo, which contains lots of useful information such as the
MediaCodec name, the codec capabilities, etc.
PiperOrigin-RevId: 323575782
*** Original commit ***
Pass startPositionUs into Renderer.replaceStream
Plumb this down into BaseRenderer.onStreamChanged and use it when
deciding whether to render the first frame of a new period.
***
PiperOrigin-RevId: 323447253
This allows us to enforce the limit because the array can only be
reassigned through reset(byte[]) or reset(byte[], int) (which update
the limit)
PiperOrigin-RevId: 323339960
This removes Supplier, Function and Predicate. Consumer is kept because
Guava doesn't have an equivalent (Java 8 does, but we can't use that
yet).
#exofixit
PiperOrigin-RevId: 323324392
We currently mix point-based systems with Comparable-based systems.
This switches all scoring to using Comparable and modernizes it by
using ComparisonChain.
Using Comparator chains is more maintainable than point systems because
the reader doesn't have to think about all combinatorial combinations
of points.
PiperOrigin-RevId: 322766278
These callbacks were only necessary to track the queue in AnalyticsCollector and there is no other known benefit of having them.
PiperOrigin-RevId: 322535274
getExoMediaCryptoType will only return null for drmInitData == null and
track types for which placeholder sessions are not used. This change
will allow renderers to abstract themselves from format.drmInitData.
PiperOrigin-RevId: 322131219
Replace `type` with (optional) `mimeType` and add `keySetId` in
DownloadRequest. The DownloadHelper infers the downloading method (DASH,
HLS, SmoothStreaming or Progressive) from the content's MIME type and
URI.
PiperOrigin-RevId: 322117384
The logic to clear the playlist is currently duplicated in various
reset methods so that calls to player.stop(true) can clear the playlist.
This can be deduplicated by clearing the playlist as a seperate
operation that reuses the existing code.
PiperOrigin-RevId: 321578759
We currently try to call onAdPlaybackStarted even if the ad session
is not created yet and if not, we never call the callback afterwards.
Make sure to update and create the current session before trying to
send onAdPlaybackStarted.
As a result, we can merge updateSessions into the existing
handleTimelineChanged and handleDiscontinuity calls as they always
need to be called together.
PiperOrigin-RevId: 321383860
Float values are allowed to be > 0dbfs,
it is just not nominal as it will might
distort the signal when played without
attenuation.
This is also consistent with
[AudioTrack.write(FloatBuffer)](https://developer.android.com/reference/android/media/AudioTrack#write(float[],%20int,%20int,%20int)) that explicitly
allows it up to 3dbfs.
PiperOrigin-RevId: 321345077
The method has been called from two call sites in EPII triggered by EPII.updatePeriods(). The first call site was calling it when the MediaSourceList is empty or not yet prepared. This can be removed because if empty or not prepared no source ever could have thrown yet.
The second call site was checking for potential source refresh exceptions when queue.getNextMediaPeriodInfo() returns null when trying to getting the next loading period. Looking into all reasons for why the method returns null, none of them is caused by an exception of a media source. The reasons are:
- if we are at the last period of the timeline
- if the defaultPosition of the next period in the timeline is null (if the window.durationUs == C.TIME_UNSET or defaultPositionProjectionUs is projected beyond the duration of the window)
- if we are waiting for an ad uri to arrive (period.isAdAvailable(...) == false)
- if we are waiting for the ad group count to be updated (adCountInCurrentAdGroup == C.LENGTH_UNSET)
The above reasons are not caused by a source error and may be resolved when doSomeWork is called the next time. Hence it is save to remove the calls to maybeThrowSourceInfoRefreshError().
Beside this, an actual sourceInfoRefreshError will be reported by maskingMediaSource.maybeThrowPrepareError(), which is called each time doSomeWork() is called and the playing period is not yet prepared (EPII:L836). So the player is notified by source errors that way, which confirms removing the above calls is fine.
PiperOrigin-RevId: 321331777
Plumb this down into BaseRenderer.onStreamChanged and use it when
deciding whether to render the first frame of a new period.
PiperOrigin-RevId: 321175627
This change masks playbackInfo.periodId and playbackInfo.loadingPeriodId for operations which change these periods (set/add/remove sources and seeks).
Because this masking is reflected in the playbackInfo object, player attributes can be retrieved without the maskingXyz variables in EPI. This has the advantage that the playbackInfo object always reflects the public state of the player even when operations are still pending. The maskingXyz variables in EPI are only required for the deprecated use case of an initial seek in an empty timeline.
PiperOrigin-RevId: 321160092
In order to use DeviceInfo class in media2, this CL moves the class to
common module. It didn't move the other file in the same package,
DeviceListener, as it's for DeviceComponent but media2 SessionPlayer
doesn't have components as it is already flattened. PlayerCallback will
have equivalent methods of DeviceListener.
PiperOrigin-RevId: 321154997
The method currently advances the read position and returns the number
of skipped samples. This prevents checking how many samples are skipped
before the operation is executed.
Instead, we have a new method that returns the number of to be skipped
samples and a skip method that executes the skipping.
PiperOrigin-RevId: 320953439
- DefaultAudioSink always supports floating point input. Make it
advertise this fact.
- Remove the ability to enable/disable floating point output in
FfmpegAudioRenderer, since this ability is now also provided on
DefaultAudioSink.
- Let FfmpegAudioRenderer query the sink to determine whether it
will output floating point PCM directly or resample it to 16-bit
PCM.
PiperOrigin-RevId: 320945360
Sharing the Handler has led to it being accidentally used for purposes
beyond the original intention.
Instead for EPII -> EPI communication: Call methods directly on
ExoPlayerImpl that then post from the playback thread to the
application thread.
And for the MediaSourceList and Queue initialization, create a dedicated
Handler based on the same applicationLooper.
PiperOrigin-RevId: 320590527
Also flip DefaultDrmSessionManager#prepare()/release() into guard
clauses.
Suggestions from review comments on:
316f8a88cd
PiperOrigin-RevId: 320572462
AdDisplayContainer now takes the video ad player at construction time,
and obstructions are registered/unregistered via a new method. Also
'content complete' is now notified via ad callbacks rather than the
AdsLoader.
PiperOrigin-RevId: 320567666
DecoderCounters are reset in onEnabled, but the way the local
counters in MediaCodecVideoRenderers were reset assumed the
DecoderCounters were reset in onStarted.
PiperOrigin-RevId: 320440991
Building on the Format that was provided on the input side of the
decoder creates a format that's a mixture of the formats on the
input and output sides of the decoder. This change instead builds
a PCM format from scratch.
PiperOrigin-RevId: 320405656
The renderers are currently constructing formats that consist of their
input format with added PCM encoding. Such formats are not self-consistent,
and this only works because DefaultAudioSink ignores the rest of the
format if the format has a PCM encoding. It would not work if the sink
implementation checked the MIME type, for example, which wouldn't be a
strange or incorrect thing for it to do.
The more correct approach is to construct a new format that properly
represents the PCM that will be provided to the sink.
This change also renames supportsOutput to supportsFormat, because
AudioSink itself has both an input and an output side, and this method
is actually evaluating support on the input side of the sink.
PiperOrigin-RevId: 320396089
This is useful for subclasses to easily query the point up to which
they should only decode (but not render) content, rather than each
subclass having to have its own startPositionUs and update it in
onPositionReset.
PiperOrigin-RevId: 320163677
*** Original commit ***
Stop parsing unsupported WebVTT CSS properties
The spec lists an exhaustive list of CSS properties that should be
recognised, all others must be ignored:
https://www.w3.org/TR/webvtt1/#the-cue-pseudo-element
***
PiperOrigin-RevId: 320150427
*** Original commit ***
Rollback of 0943886cbd
*** Original commit ***
Use last queue format instead of previous decision to select new track
We currently use the save...
***
PiperOrigin-RevId: 320015109
*** Original commit ***
Use last queue format instead of previous decision to select new track
We currently use the saved selectionIndex to base our new track
selection decision on. This index might be stale if the previous
selection didn't result in a queue update (e.g. when loading live
streams where the new chunk isn't available yet).
Fix this by using the format of the last chunk to make the new decision.
Issue: #7582
***
PiperOrigin-RevId: 319991676
We currently use the saved selectionIndex to base our new track
selection decision on. This index might be stale if the previous
selection didn't result in a queue update (e.g. when loading live
streams where the new chunk isn't available yet).
Fix this by using the format of the last chunk to make the new decision.
Issue: #7582
PiperOrigin-RevId: 319957980
The wait time parameter is an implementation detail where we can just
provide a default.
In addition, we should also force the evaluation when the last chunk
in the queue changed to ensure it is always evaluated before starting
to load a new chunk.
Issue: #7582
PiperOrigin-RevId: 319949251
This is a partial revert of 0a2bacb7b7. I've added a comment
explaining why the code path is necessary after all, to avoid
future confusion.
PiperOrigin-RevId: 319822696
Clearing the exception puts the SimpleDecoder into a silent failure
state - the decoder thread is dead (because decode() has returned
false) but it's still possible to queue buffers to the decoder (they
just never get decoded). This partially reverts
4107375c9d
Also always recreate the decoder when handling an error in TextRenderer
This ensures we can try and decode a later subtitle sample after
encountering a decode error. This behaviour is what nulling out the
exception in SimpleDecoder.flush() was trying to achieve. We need to
ensure we don't start passing data to the new decoder until we've
hit the next key frame, so we throw away any non-keyframe samples
inside TextRenderer#render().
Issue: #7590
PiperOrigin-RevId: 319785908
We currently try to keep track of the playback queue (MediaPeriodQueue)
by listening to onMediaPeriodCreated/onMediaPeriodReleased events.
This approach has some problems:
1. It's easily broken by custom MediaSources that don't report these
events correctly.
2. We need to make some assumptions about what the order of these
events actually means. For example it is currently important that
the playing period gets released last in MediaPeriodQueue.clear()
3. We don't see batched events (like MediaPeriodQueue.clear()), so that
it is impossible to keep the "last reading period" for example. This
information is needed to correctly associate renderer errors to
periods after the queue has been cleared.
All of these problems can be solved by directly tracking the queue.
This also makes the onMediaPeriodCreated/Released/ReadingStarted events
obsolete and they can be removed in a future change.
PiperOrigin-RevId: 319739993
The current code only works if the tts:ruby attributes are defined
directly on the in-line elements. This changes that so we also consider
tts:ruby attributes on `style` nodes referenced by ID.
PiperOrigin-RevId: 319515177
We don't need the renderer immediately after stopping, so the
renderer should not throw a checked exception until it's used again.
This is inline with the not throwing from disable().
Also, none of the known implementation throw an exception at the moment
and all reasonable base classes omit the throws clause already.
PiperOrigin-RevId: 319503643
They are all for Context.getSystemService that is allowed to return
null. In most cases where we need to service, we make an assertion that
it is available.
PiperOrigin-RevId: 319503557