In the test, a real instance of SimpleExoplayer plays two identical Mp3 files.
The GaplessMp3Decoder will write randomized data to decoder output on receiving
input. The test compares the bytes written by the decoder with the bytes
received by the AudioTrack, to verify that the trimming of encoder delay/
padding is correctly carried out.
Test mp3 has delay 576 frames and padding 1404 frames. File generated from:
ffmpeg -f lavfi -i "sine=frequency=1000:duration=1" test.mp3
This change needs robolectric version 4.5, which is not currently released (2020 Sep 30).
PiperOrigin-RevId: 334648486
Non-realtime AudioTrack playback speed was not taken into account when
extrapolating the old mode's position, causing the position not to
advance smoothly.
This should be a no-op when not using AudioTrack playback params for
speed adjustment.
Issue: #7982
PiperOrigin-RevId: 334151163
Remove the SynchronousMediaCodecBufferEnqueuer interface
since we only keep the AsynchronousMediaCodecBufferEnqueuer
implementation.
PiperOrigin-RevId: 333701115
Retry AudioTrack init and write for 100ms before
giving up and aborting playback.
This was tested by throwing every 2 init/write and
making sure playback did not stopped.
#exo-offload
PiperOrigin-RevId: 333536841
This issue has been observed on a test app stress
testing setEndOfStream.
The issue has not been observed on ExoPlayer,
probably due to timing differences, but it is fixed
preventively.
#exo-offload
PiperOrigin-RevId: 333472136
We have a workaround for uneven sample stream durarions in playlists that
assumes a renderer allows playback if it's reading ahead or waiting for
the next stream.
652c2f9c18 changed this logic to no longer require to
wait until the next stream is prepared due to a change in how we advance
media periods in the queue. However, the code falsely still requires the
next stream to exist (even if it's not prepared). This can cause a stuck
buffering state when the difference in the duration of the streams is more
than what we buffer ahead because we never create the next stream in such
a case.
Note: DefaultMediaClock.shouldUseStandaloneClock has roughly the same logic
and also doesn't require the next stream to be present.
Also fix a test that seemed to rely on this stuck buffering case to test
stuck buffering detection. Changed the test to not read the end of stream
to ensure it runs into the desired stuck buffering case.
Issue:#7943
PiperOrigin-RevId: 333050285
Without this patch, playback would be frozen indefinitely
until the user manually pauses and unpauses it.
This has the side effect of disabling offload until
the next stop due to the workaround of
disabling offload when it encounters a failure.
As an audio server crash is considered very
infrequent, especially in stable conditions like
an audio only playback, it is unlikely that disabling
offload is an issue.
PiperOrigin-RevId: 332857094
This test is intended to check that DefaultLoadControl will cause
playback to fail as "stuck buffering" rather than OOM-ing, in the
case that its target buffer size is reached and playback still
hasn't started.
Unfortunately, the target buffer size is ~130MB, and when running
on some setups an OOM actually ends up happening before this much
memory is allocated.
This change makes the target buffer size much smaller to avoid the
problem.
PiperOrigin-RevId: 331748208
This may remove available memory from other tests running in the same
process. Instead, create the huge buffer when needed so it can be GCed
immediately.
PiperOrigin-RevId: 330960844
When passing in ExtractorFactory instances to SimpleExoPlayer.Builder or
DefaultMediaSourceFactory, we currently need to pass in one other
instance (RenderersFactory or DataSource.Factory), that developers will
often set to its default. To avoid specifying these defaults, these new
convience methods allow to just set the ExtractorsFactory if required.
PiperOrigin-RevId: 330908002
This allows to customize extractor flags more easily when setting up the player.
In addition, we need to provide a way to pass in the ExtractorFactory through
the constructor chain starting in SimpleExoPlayer so that removing the
DefaultExtractorsFactory is possible for R8.
PiperOrigin-RevId: 330472935
- Use a setter, which is consistent with how other optional
components are passed.
- Remove nesting where a provider provides another provider.
Since AdSupportProvider then only provides one thing, it
can be renamed to AdsLoaderProvider, which more clearly
expresses what it provides.
PiperOrigin-RevId: 330396334
In maybeInitCodecWithFallback, it caches availableCodecInfos with mediaCryptoRequiresSecureDecoder and inputFormat as inputs, and won't clear it if shouldInitCodec is false, resulting in a case where availableCodecInfos is not null and codec is null.
When we have a new format, it's reasonable to clear availableCodecInfos if codec is null. Otherwise we might not be able to properly initialize a new codec.
PiperOrigin-RevId: 329971796
1. Add EventLogger right away in PlayerActivity, else it doesn't log
playWhenReady being initially set to true.
2. Remove EventLogger logging for the audio position advancing. It's
redundant with isPlaying logging unless you're very specifically
interested in the timing difference.
3. Remove unnecessary comment in Player.
4. Fix Timeline Javadoc.
PiperOrigin-RevId: 328983944
In 2.11.2 to 2.11.5, we considered all AAC streams as consisting
only of sync samples. In 2.11.6+, we considered no AAC streams as
consisting of sync samples, because the property is not guaranteed
specifically for xHE-AAC. This will have caused a small regression
is seek speed for some types of media.
This change brings back the optimization for AAC, specifically
excluding only xHE-AAC (and cases where we don't know what type of
AAC we're dealing with).
PiperOrigin-RevId: 328950697
To play slow motion streams where the audio has been recorded at
slower speeds, it is necessary to be able to resample (rather than
time-stretch) the audio. This change undeprecates back the previously
deprecated PlaybackParameters class to allow apps to set pitch.
PiperOrigin-RevId: 328703116
We currently always reset everything if playingPeriod != readingPeriod.
However, this is only needed when the pausing is actually required, i.e.,
if the feature is enabled and we are in the last period of the window.
PiperOrigin-RevId: 328141242
Currently the audio renderer can become ready before the AudioTrack
actually has enough data to play something, which means that the
player may transition to the ready state before audio starts
playing. This makes the player's current state transition not very
useful for detecting when audio actually starts playing.
This change adds a new event to notify apps when the audio position
is increasing after a pause or seek/flush/reset event, and includes
an estimate of the system time at which audio playout started.
Issue: #7577
PiperOrigin-RevId: 327810040
This allows us to more easily create different dumps derived from the
same assets.
This moves media/source files from `assets/` to `assets/media/` and
dump files from `assets/` to `assets/extractordumps/` and
`assets/audiosinkdumps/` as appropriate. I intend to add
`assets/playbackdumps/` in a future CL.
PiperOrigin-RevId: 326986283
AudioTrack.setPlaybackParams can be used to adjust playback speed.
This is preferable to application-level speed adjustment (currently
implemented in ExoPlayer) from API 23 because the speed change
occurs in the mixer, which means that the audio track buffer doesn't
need to drain out before the speed adjustment takes effect.
Issue: #7502
PiperOrigin-RevId: 326392301
formatSupport is a 2-dimensional int array but it's documented as
being indexed by 3 things. This seems to be a copy-paste mistake in
e97b8347eb
selectAllTracks() takes a 3-dimensional array with the same
3-indexed documentation, which makes sense there.
Also rename formatSupports -> formatSupport for consistency.
PiperOrigin-RevId: 325779435
Use a dedicated boolean to track if we've notified the current surface,
rather than re-using rendereredFirstFrameAfterReset.
PiperOrigin-RevId: 325757948
*** 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