Commit graph

241 commits

Author SHA1 Message Date
tofunmi
d4b452d475 Use ProgressiveMediaSource and period for images
PiperOrigin-RevId: 555424664
2023-08-10 12:30:29 +00:00
rohks
481ea4a274 Enhance continueLoading() API to allow passing more information
Modifies the `SequenceableLoader.continueLoading(long)` method in the `SequenceableLoader` interface to `SequenceableLoader.continueLoading(LoadingInfo)`.

`LoadingInfo` contains additional parameters, including `playbackSpeed` and `lastRebufferRealtimeMs` in addition to the existing `playbackPositionUs`. The additional parameters will allow us to pass these information to Common Media Client Data (CMCD) logging.

By using the `LoadingInfo` object, we ensure future flexibility to add more fields without causing any breaking changes to the API.

PiperOrigin-RevId: 555123961
2023-08-10 12:16:41 +00:00
michaelkatz
aed21e464e Fix last sample detection issue for ClippingMediaSource
If stream is not considered final and `ClippingMediaSource` is read to `endUs`, then `BaseRenderer.readSource` returns `C.RESULT_NOTHING_READ`. In that case, the `lastBufferInStreamPresentationTimeUs` is not set and the last frame is not rendered.

PiperOrigin-RevId: 554418971
2023-08-07 11:34:34 +00:00
tonihei
a3c1d5be9d Reset loading period after reading discontinuity that requires loading
This is the same change as 8655429af7, just on the second call site
of readDiscontinuity. The tests didn't cover this case yet because
they never queued more than 2 items in a playlist.

PiperOrigin-RevId: 553485244
2023-08-07 11:30:38 +00:00
tonihei
69656774f9 Only use first frame stream start position check at stream transitions
We currently only force the first frame if the frame timestamp is
greater than the stream *offset*.

This is wrong for two reasons:
 1. The timestamp and the offset are not comparable and it should be
    the stream start position.
 2. The check should only be applied at stream transitions where we
    need to make sure that a new first frame isn't rendered until we
    passed the transition point.

We have to fix both issues together, because fixing just issue (1)
causes seeks to before the start position to no longer render the
frame (and playback will be stuck). A new test covers this case.

We also amend the stream transition test case to actually test what it
promises to test and add a test for prerolling samples at the
beginning, to ensure the first frame is still renderered.

Issue: androidx/media#291
PiperOrigin-RevId: 552858967
2023-08-07 11:21:08 +00:00
rohks
11648e6c8e Simplify and accurately compute chunk duration
Refactored `CmcdLog` to `CmcdHeadersFactory` for improved representation of its purpose and updated implementations.

#minor-change

PiperOrigin-RevId: 552831995
2023-08-07 11:19:00 +00:00
tonihei
79c8b0e0f8 Set correct start time for newly enabled renderers during playback
We currently pass in the time at which the stream originally started,
but newly enabled renderers should get the current playback position
instead.

PiperOrigin-RevId: 550894630
2023-08-01 14:04:35 +01:00
jbibik
25253698bc TtmlParser implementation - moved from TtmlDecoder
`TtmlDecoder` which used to be `SimpleSubtitleDecoder` will now be called `TtmlParser` and implement SubtitleParser interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `TtmlParser` instance.

PiperOrigin-RevId: 549700490
2023-08-01 13:43:12 +01:00
jbibik
1c1b78e635 Test for Decoder with Mp4WebvttParser corrected
PiperOrigin-RevId: 549629289
2023-08-01 13:42:06 +01:00
tonihei
85cde93e6c Remove C2Mp3TimestampTracker
This tracker aims to replicate the behavior of a specific codec to
ensure MediaCodecRenderer correctly detects stream and output
format transitions. The class was needed because MediaCodecRenderer
made assumptions about codec behavior this codec did not fulfil (in
particular, changing timestamps and number of samples).

Since then, MediaCodecRenderer was made more robust to this kind of
codec behavior in general and currently has no assumptions that
require any special handling of this codec. This means we can remove
the workaround completely.

PiperOrigin-RevId: 549610989
2023-08-01 13:39:53 +01:00
ibaker
1cfaae3450 Enable WebVTT subtitles in MkvPlaybackTest
This is no longer flaky because WebVTT subtitles are decoded on the
loading thread (enabled in this test with
`defaultExractorsFactory.setTextTrackTranscodingEnabled(true)` - and
supported for WebVTT since f0f24aa0d4).

PiperOrigin-RevId: 549594291
2023-08-01 13:35:11 +01:00
rohks
cdb174c91a Add field measured throughput (mtp)
Updated `ExoTrackSelection` to provide the most recent bitrate estimate, enabling the inclusion of measured throughput (mtp) as a CMCD-Request field in Common Media Client Data (CMCD) logging.

Additionally, made changes to the `checkArgument` methods in `CmcdLog` to prevent the use of default values in certain cases.

#minor-release

PiperOrigin-RevId: 549369529
2023-07-20 10:34:32 +01:00
jbibik
f0f24aa0d4 WebvttParser implementation - moved from WebvttDecoder
`WebvttDecoder` which used to be `SimpleSubtitleDecoder` will now be called `WebvttParser` and implement `SubtitleParser` interface.

For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `WebvttParser` instance. `WebvttSubtitle` will still be used behind the scenes to handle overlapping `Cues`.

PiperOrigin-RevId: 549298733
2023-07-20 10:32:13 +01:00
ibaker
5d453fcf37 Add an Extractor to parse subtitles before SampleQueue
The end-to-end test output for the overlapping SRT and SSA subtitles
is currently incorrect. They will be fixed in a future change that
updates `TextRenderer` to support this overlap.

The 'extra' samples visible in the extractor test output files are
'empty cue list' samples produced by `SsaParser`. They will go away
when this implementation is updated to remove this behaviour and rely
on `CuesWithTiming.durationUs` instead (the 'empty list' behaviour is
not required by the `SubtitleParser` interface).

PiperOrigin-RevId: 549264593
2023-07-20 10:30:16 +01:00
tonihei
da99f9937d Rollback of 7996766b22
*** Original commit ***

Rollback of b69b33206e

*** Original commit ***

Mark output sample as decode-only based on start time

We currently do the same check on the input timestamps and
expect the output timestamps to match. Some codecs produce
samples with modified timestamps and the logic is a lot safer
when the comparison with the start time is done on the output
side of the codec.

Issue: google/ExoPlayer#11000

***

***

PiperOrigin-RevId: 549019403
2023-07-20 10:26:25 +01:00
jbibik
9520180fbb DelegatingSubtitleDecoder tests refactor
PiperOrigin-RevId: 548991428
2023-07-20 10:21:43 +01:00
rohks
1b2a2fcde0 Add fields top bitrate(tb) and object duration(d)
Added these CMCD-Object fields to Common Media Client Data (CMCD) logging.

#minor-release

PiperOrigin-RevId: 548950296
2023-07-20 10:19:26 +01:00
tonihei
8655429af7 Reset loading period after reading discontinuity that requires loading
Reading a discontinuity from a media period indicates that a position
reset is required. As part of this event, the media period may need
further loading (e.g in a MergingMediaPeriod where one stream reported
a discontinuity and the other need to reload from this position).

This currently fails if the media periods was already fully loaded and
we started loading further items in the playlist. As a result, playback
is stuck forever. We can fix this by detecting that further loading is
needed and resetting the loading period to the current one.

The existing MergingPlaylistPlaybackTest already covers this case
reliably, because it combines all the right preconditions (merging
source, clipping to get a discontinuity and a playlist).

PiperOrigin-RevId: 548735177
2023-07-20 10:17:11 +01:00
ibaker
34768c2399 Add MKV test assets with overlapping SSA and SRT subtitles
This is a step towards adding general support for overlapping
subtitles in these formats (and others), both muxed and sideloaded:
* Issue: google/ExoPlayer#10295
* Issue: google/ExoPlayer#4794

This change adds these files to the end-to-end playback tests too, but
the subtitle track is currently disabled because renderer-side subtitle
parsing causes flaky tests (due to an uncontrolled thread in
`SimpleSubtitleDecoder`). The subtitle track will be re-enabled in
a follow-up change when loading-side subtitle parsing is added (so the
tests will no longer be flaky). At this point the overlapping subtitles
**still** won't be supported end-to-end, but a second change will
resolve this will changes in `TextRenderer` - which will change the
end-to-end playback dumps to reflect the overlapping subtitles.

PiperOrigin-RevId: 548705032
2023-07-20 10:14:50 +01:00
tonihei
c64d9fd6da Fix race condition in clipped sample streams
The streams return end-of-input if they read no samples, but know that
they are fully buffered to at least the clipped end time. This helps to
detect the end of stream even if there are no new buffers after the end
of the clip (e.g. for sparse metadata tracks).

The race condition occurs because the buffered position is evaluated
after reading the sample. So between reading "no sample" and checking
the buffered position, the source may have loaded arbitrary amounts
of data. This may lead to a situation where the source has not read
all samples, reads NOTHING_READ (because the queue is empty) and then
immediately returns end-of-stream (because the buffered position
jumped forward), causing all remaining samples in the stream to be
skipped. This can fixed by moving the buffered position check to
before reading the sample, so that it never exceeds the buffered
position at the time of reading "no sample".

#minor-release

PiperOrigin-RevId: 548646464
2023-07-20 10:10:00 +01:00
jbibik
7537e692c6 Tx3gParser implementation - moved from Tx3gDecoder
`Tx3gDecoder` which used to be `SimpleSubtitleDecoder` will now be called `Tx3gParser` and implement `SubtitleParser` interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `Tx3gParser` instance.

PiperOrigin-RevId: 548144492
2023-07-20 10:01:21 +01:00
tonihei
568817f756 Add e2etests for merged sources in a playlist
These tests allow to verify the samples sent for decoding,
when decoders are reset, which samples are dropped as decode-only
for video and which samples are sent to the AudioTrack for playback.

The test exercises all combinations of merges where audio or video
is the primary track and where audio, video or both are clipped.

PiperOrigin-RevId: 548061254
2023-07-14 10:23:01 +01:00
tonihei
989607aa04 Add e2etest for clipped sources in playlists
These tests allow to verify the samples sent for decoding,
when decoders are reset, which samples are dropped as decode-only
for video and which samples are sent to the AudioTrack for playback.

The test exercises all combinations of clipping transitions for
sources that are either clipped at the start, the end, or both.

PiperOrigin-RevId: 547730824
2023-07-13 16:00:16 +01:00
tonihei
d8498f3ecb Set signal on renderer once it's allowed to render start of stream
When a renderer is pre-enabled (while another playback is still
ongoing), we pass mayRenderStartOfStream=false to Renderer.enable.
This ensures we don't show any first frames while the previous media
is still playing.

Currently, we never tell the renderer when we actually stop playing
the previous media so that it could render the start of the stream,
because we allow this as soon as the renderer is in STATE_STARTED and
we assume that we have to be in STATE_STARTED to make this stream
transition.

While this assumption is true, there are also cases where we can't
start the renderers because they are not ready yet and the video
renderer can't become ready because it didn't render its first frame.
This effectively blocks playback forever.

The most direct way of solving this, is to tell the renderer that
playback has transitioned and that it is now allowed to render the
start of the stream. This means it can never get blocked as described
above.

PiperOrigin-RevId: 547727347
2023-07-13 15:59:00 +01:00
rohks
0412a36564 Add fields streaming format(sf), stream type(st) and version(v)
Added these CMCD-Session fields to Common Media Client Data (CMCD) logging.

#minor-release

PiperOrigin-RevId: 547435498
2023-07-13 15:50:16 +01:00
jbibik
02b9d8d8b7 Mp4WebvttParser implementation - moved from Mp4WebvttDecoder
`Mp4WebvttDecoder` which used to be `SimpleSubtitleDecoder` will now be called `Mp4WebvttParser` and implement `SubtitleParser` interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `Mp4WebvttParser` instance.

PiperOrigin-RevId: 547248157
2023-07-13 15:46:44 +01:00
tonihei
5c8b142174 Fix inconsistency in SampleQueue seek for sync-sample-only formats
For sync-sample-only formats, we have an optimization to drop all buffers
with less than the start time when writing them to the queue.

For the same formats, if we set a new start time (=seek), we only seek
to the buffer at or before the start time. This means the first sample
in the queue is different depending on whether we seek to a start time
or set a start time and then write samples. This is inconsistent and
effectively means the first sample depends on a race condition between
the Loader thread (writing samples) and the playback thread (attempting
an initial seek in the already loaded samples).

The effect of this inconsistency is that we have to decode one sample
we don't need (and could have skipped) and that some tests become flaky
if the test setup runs into the mentioned race condition.

The fix is to change the SampleQueue seek method to also seek to
a sample at or after the specified time, to align the behavior to the
case where we write the same samples to an empty queue.

The change also clarifies the Javadoc of
MimeTypes.allSamplesAreSyncSamples to note that this should really only
return true if the samples have no "duration" that matters. Otherwise,
we could reasonably return true for most subtitle formats although it
would break subtitle display because we'd remove samples that start
before the seek time.

PiperOrigin-RevId: 547189941
2023-07-13 15:41:49 +01:00
tonihei
d6f20455ac ServerSideAdInsertionMediaSourceTest adjustments
Some adjustments to the test to make it more correct and prevent it
from becoming flaky:
 - Use separate output dump files per test setup. Once we add more data
   to these files, they are not guaranteed to be the same anymore.
 - Use a seek position that is actually behind the midroll as described
   in the test setup.
 - Change ad insertion position to ensure the ad group duration doesn't
   exceed the underlying media duration.
 - Add a wait for isLoading to ensure the late insertion of an ad group
   happens consistently at the same processing stage.

PiperOrigin-RevId: 546825183
2023-07-13 15:28:54 +01:00
tonihei
3d4bd7ce19 Make MediaItems updateable
This changes all MediaSources in our library to allow updates to
their MediaItems (if supported).

Issue: google/ExoPlayer#9978
Issue: androidx/media#33
PiperOrigin-RevId: 546808812
2023-07-13 15:26:30 +01:00
jbibik
ca483a3c2c SubripParser implementation - moved from SubripDecoder
`SubripDecoder` which used to be `SimpleSubtitleDecoder` will now be called `SubripParser` and implement `SubtitleParser` interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `SubripParser` instance.

PiperOrigin-RevId: 546538113
2023-07-13 15:21:55 +01:00
jbibik
377d8edf9c SsaParser implementation - moved from SsaDecoder
`SsaDecoder` which used to be `SimpleSubtitleDecoder` will now be called `SsaParser` and implement `SubtitleParser` interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `SsaParser` instance.

PiperOrigin-RevId: 546336035
2023-07-13 15:20:34 +01:00
tonihei
c6e7c54140 Release surface in e2etests
Robolectric writes warnings to the log output because the Surfaces
we create are not released and pollute the test environment. This
causes performance issues if tests are run repeatedly.

PiperOrigin-RevId: 545906757
2023-07-13 14:58:55 +01:00
tonihei
63331dbd1b Use Clock in video renderers
This makes tests more realistic because the returned value matches
the rest of the simulated test time.

It also prevents test flakiness in (yet to be written) tests that
may accidentally drop output buffers or calculate the wrong values.

PiperOrigin-RevId: 545690008
2023-07-13 14:54:10 +01:00
michaelkatz
5737e415b8 Cache rawPlaybackHeadPosition across reset due to track transition
Upon track transition of offloaded playback of gapless tracks, the framework will reset the playback head position. The AudioTrackPositionTracker must be made to expect the reset and cache accumulated sum of rawPlaybackHeadPosition.

#minor-release

PiperOrigin-RevId: 545602979
2023-07-05 13:57:29 +00:00
tonihei
aa57d48347 Add MediaSource.canUpdateMediaItem/updateMediaItem
This allows MediaSources to accept MediaItem updates after creation.

This CL adds the handling and plumbing logic in `ExoPlayerImpl`,
`ExoPlayerImplInternal`, `MediaSourceList` and `MaskingMediaSource`.

It also updates all forwarding/wrapping sources to forward these calls
to their wrapped instance.

The actual functionality is only added to `FakeMediaSource` instances in
tests so far.

PiperOrigin-RevId: 545450210
2023-07-05 09:21:22 +00:00
ibaker
a783d704b2 Add duration to text/x-exoplayer-cues binary format
This plumbs a duration through `SampleQueue` which will make it easier
to handle transcoding muxed subtitles from e.g. SubRip to
`text/x-exoplayer-cues`.

This change is a no-op to the end-to-end behaviour of ExoPlayer because
currently we only support parsing sideloaded subtitles before
`SampleQueue`, and by adding the duration we don't affect the cues that
are ultimately output by `Player.Listener.onCues` (as shown by no change
to the golden files for `WebvttPlaybackTest` in this commit).

I considered making `CuesWithStartTimeAndDuration` implement
`Bundleable` (and deleting `CueEncoder/Decoder`) but decided against
it because we are deliberately not encoding `startTimeUs` (since that's
encoded as the sample time in `SampleQueue`). I also considered
introducing another type that only has `List<Cue>` and `durationUs`
fields, but it didn't seem necessary, since we want `startTimeUs`
everywhere else (except inside `SampleQueue`).

PiperOrigin-RevId: 545226847
2023-07-05 09:14:38 +00:00
Googler
58180a0f2a Rename certain tests and modify documentation.
PiperOrigin-RevId: 544664238
2023-07-05 08:56:46 +00:00
Googler
832d5b5f98 Update playback suppression states dynamically.
Instead of playing or pausing itself, the ExoPlayer implementation should only update the playback suppression reason as and when audio outputs are added or removed dynamically.

PiperOrigin-RevId: 544379033
2023-06-29 23:16:39 +00:00
tianyifeng
d895a46b28 Ensure that ShuffleOrder has the same length as the current playlist
Add a fail-fast check in `ExoPlayerImpl` to ensure the equality of the lengths of `ShuffleOrder` and the current playlist. Also improve the documentation of `setShuffleOrder(ShuffleOrder)` with explicit instruction on this.

Issue: androidx/media#480

#minor-release

PiperOrigin-RevId: 544009359
2023-06-29 23:10:29 +00:00
tonihei
2322462404 Do not trim audio samples by changing their timestamp
MP4 edit lists sometimes ask to start playback between two samples.
If this happens, we currently change the timestamp of the first
sample to zero to trim it (e.g. to display the first frame for a
slightly shorter period of time). However, we can't do this to audio
samples are they have an inherent duration and trimming them this
way is not possible.

#minor-release

PiperOrigin-RevId: 543420218
2023-06-29 22:50:04 +00:00
tonihei
7996766b22 Rollback of b69b33206e
*** Original commit ***

Mark output sample as decode-only based on start time

We currently do the same check on the input timestamps and
expect the output timestamps to match. Some codecs produce
samples with modified timestamps and the logic is a lot safer
when the comparison with the start time is done on the output
side of the codec.

Issue: google/ExoPlayer#11000

***

PiperOrigin-RevId: 543379665
2023-06-26 11:39:52 +00:00
jbibik
ea0f564c1e Fix missing equals sign in inline-comment parameter names
PiperOrigin-RevId: 542577676
2023-06-23 16:44:33 +00:00
tonihei
e0191ddded Fix spurious sessions created for events after the playlist is cleared
Some events may arrive after the playlist is cleared (e.g. load
cancellation). In this case, the DefaultPlaybackSessionManager may
create a new session for the already removed item.

We already have checks in place that ignore events with old
windowSequenceNumbers, but these checks only work if the current
session is set (i.e. the playlist is non-empty). The fix is to add
the same check for empty playlists by keeping note of the last
removed window sequence number.

PiperOrigin-RevId: 541870812
2023-06-20 14:08:06 +01:00
sheenachhabra
911a6430f3 Remove UdtaInfo class
The class seems unnecessary and the code can be simplified by
removing this.

PiperOrigin-RevId: 541675378
2023-06-20 14:00:50 +01:00
rohks
be9b057dda Refactor method CmcdLog.createInstance to accept bufferedDurationUs
Instead of providing `playbackDurationUs` and `loadPositionUs` individually, which are used to calculate the buffer duration for CMCD logging, we can directly pass the pre-calculated `bufferedDurationUs` available in the `getNextChunk` method of the chunk source classes.

Issue: google/ExoPlayer#8699

#minor-release

PiperOrigin-RevId: 540630112
2023-06-19 16:19:04 +01:00
Googler
42915e9a58 Rename the APIs for playback suppression due to unsuitable output.
The APIs /related fields for playback suppression due to unsuitable output should be renamed from '..SuppressPlaybackWhenNoSuitableOutputAvailable' to '..SuppressPlaybackOnUnsuitableOutput'

PiperOrigin-RevId: 540555715
2023-06-19 16:12:33 +01:00
bachinger
bd97dd8519 Rollback of 7956c80f73
*** Original commit ***

Rollback of 2a6f893fba

*** Original commit ***

Set video size to 0/0 when video render is disabled

In terms of MCVR wi...

***

PiperOrigin-RevId: 540525069
2023-06-19 16:09:13 +01:00
tonihei
51fb72b00d Replace deprecated NullableType from checkerframework with our own one
The existing NullableType has been deprecated 5 years ago and causes
crashes in Kotlin apps because Kotlin doesn't recognize this annotation
as a nullable type annotation.

While we can't align on a single @Nullable annotation yet, we can at
least replace this one by JSR305's @Nonnull(MAYBE) as it fulfils all
requirements, including full Kotlin compatiblity. To avoid the
cumbersome name, we can redefine it as our own @NullableType
annotation. (We can't use @Nullable to avoid name clashes with the main
@Nullable annotation from AndroidX)

Issue: google/ExoPlayer#6792
PiperOrigin-RevId: 540497469
2023-06-19 16:08:20 +01:00
ibaker
567890da9e Remove = from parameter args in call to Constructor.newInstance
These comments reflect the parameter names of the constructor that
we're reflectively calling, but errorprone complains that they don't
match the parameter names of `Constructor.newInstance`.

PiperOrigin-RevId: 540348118
2023-06-19 16:07:18 +01:00
sheenachhabra
d0eda433ea Replace CreationTime class with Mp4TimestampData class
PiperOrigin-RevId: 540257484
2023-06-14 20:42:36 +01:00