Commit Graph

124 Commits

Author SHA1 Message Date
Muhammad Haris d53fbaeeeb fix: Fix disappearing captions with certain input patterns (#2674)
When the subtitles are turned off, unloadTextStream() on streaming engine is called, but currentTextStream is never set to null. When the captions are turned back on, a check in player.js sees that the current text stream is not null, so it assumes it exists, and is ready to go. Thus captions are never loaded.

Clearing (setting to null) the current stream on unloadTextStream ensures the text stream is properly initialized the next time it is called, and in a state so that captions can resume being parsed.

After further investigation, it seems that the unit tests are written in a way that assumes that the text stream is nulled when unloadTextStream is called. So this fix is definitely something that we assume already happens.

Closes #2671
2020-06-24 13:12:09 -07:00
Muhammad Haris d383047de1 fix(CEA): Fix missing captions when switching streams (#2672)
During video playback, if the user switches the caption stream (e.g. CC1 to CC3 which changes languages), the first caption in the next fragment is missing.

In fragmented MP4s, the end time of a caption is determined by the start time of the next caption. Thus for the last caption in a fragment, the end time cannot be determined until the next fragment is parsed.

Before this fix: the clearing of the caption stream was being called from a chain of function calls originating from clearBuffer_() on the Media source engine. But clearing a buffer and resetting a caption stream are two independent operations. As a result, the caption parser was being reset (its buffer cleared) during video seeks, and during stream switches. This makes sense for video seeks, because the end time of the last caption in the fragment can't be determined if the entire presentation timestamp changes. However for stream switches, resetting the parser doesn't make sense. Clearing the caption parser during a stream switch would actually get rid of the last caption in that fragment (which wasn't emitted since its end time wasn't determined yet), and we would lose the data, causing the problem.

The fix is to reset (and hence clear) the caption parser during seeks, but not during stream switches.

Issue #2648
2020-06-23 16:40:35 -07:00
Joey Parrish 7e6a0f38ff fix: Correct license headers in misc. files
This corrects/normalizes license headers in misc. files, such as
config files, docs, build tools, tests, and externs.  This does not
affect the compiled output, and is only done for consistency.

Issue #2638

Change-Id: I9d8da2de55243b08d7df2b743aac73c6f15e858a
2020-06-09 16:13:56 -07:00
Joey Parrish 02379d354e fix: Abort pending requests in StreamingEngine.destroy
Closes #2619

Change-Id: I10cc2e9567720c9d021038a4da3c26b6857ec709
2020-06-08 21:28:28 +00:00
Joey Parrish ba4f1d5468 Fix type info for StreamingEngine test fakes
The StreamingEngine tests use various fakes that did not have strong
type info before.  The new Closure Compiler won't allow this, and for
good reason.  Cleaning up the type info exposed a few ways that we had
left out important things or failed to remove methods that are no
longer on the types we're faking.

We also had some fakes for StreamingEngine tests that were redundant
with strongly-typed fakes that already existed in shaka.test.  This
deduplicates them.  The fakes for StreamingEngine are now just
instances of the other fakes with specific behavior attached.

Issue #2528

Change-Id: I0da67bea462e855fcfcb1b391fe83027ffa70702
2020-04-30 19:32:30 -07:00
Joey Parrish 342d35f4f9 Fix issues with nullability of numbers
Various issues with the nullability of number types led to various
fixes, including:
 - defaulting a nullable number to 0 to avoid propagating a null value
   through calculations
 - adding an assertion or runtime check that something is not null
 - moving an existing null check to before the calculation
 - returning early on null during an iteration
 - changing a nullable number to non-nullable
 - defaulting to NaN instead of null

These issues were caught by a compiler upgrade.

Issue #2528

Change-Id: I86d516c74a42ee3624c33d7513d2d4c76d3ea589
2020-04-30 16:00:00 +00:00
Joey Parrish e8ac57f36c Move drmInfos array to Stream
Period-flattening will concatenate Stream objects, so this information
should be available per-Stream instead of at the Variant level.

Issue #1339

Change-Id: I96195fea48cab1e4a349b2ab0b16064a443e928a
2020-04-09 19:22:16 +00:00
Joey Parrish 99de217c23 Remove periods from manifest structure
This removes periods from the internal manifest structure and cleans
up code and tests accordingly.  This leaves us unable to play
multi-period DASH & offline streams until the main period-flattening
algorithm is completed in shaka.util.Periods.

Three test cases have been disabled for the moment.

Multi-period playback will be restored in a smaller, more focused
follow-up commit, with disabled tests re-enabled.

Issue #1339 (flatten periods)
Issue #1698 (rapid period transitions issue)
Issue #856 (audio change causes bitrate change)
Closes #892 (refactor StreamingEngine)

Change-Id: I0cbf3b56bfdb51add15229df323b902f0b2e643a
2020-04-09 19:22:16 +00:00
Joey Parrish 1ab3f9c6db Remove position from SegmentReference
As part of Period-flattening, I'm trying to remove our dependence on
the "position" field of SegmentReference.  With that eliminated, we
can more easily concatenate Arrays of SegmentReferences without
modifying them.

 - Make SegmentIndex iterable
 - Add specialized seek() and current() methods to SegmentIterator
 - Remove position from SegmentReference
 - Make positions in SegmentIndex API stable without field in
   reference
 - Remove brittle hard-coded positions in tests (except SegmentIndex
   tests, where they would be hard to avoid in testing methods
   separately)
 - Use SegmentIterator in StreamingEngine to track the next segment
   between switches

Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)

Change-Id: I666cc21249c34ee6cbc138a59109d9f1159fa127
2020-03-23 10:09:35 -07:00
Joey Parrish 6202b9372e Revert "Move next-segment tracking to SegmentIndex"
This reverts commit 235e4e11ad.

The effort to remove SegmentReference's position field will be handled
in a different way.

Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)

Change-Id: I62b115137abc89f498b30467e574b0401dcad05d
2020-03-23 10:09:35 -07:00
Joey Parrish 235e4e11ad Move next-segment tracking to SegmentIndex
As part of Period-flattening, I'm trying to reduce our dependence on
the "position" field of SegmentReference.  If it can be eliminated, we
can more easily concatenate Arrays of SegmentReferences without
modifying them.

SegmentIndex can now track the last reference you asked for and
iterate through the list of references.  This means we don't need the
"position" field of SegmentReference, which means we don't need to
know positions in advance or globally.  StreamingEngine will no longer
use position to request segments.

The old methods find(time):position and get(position):SegmentReference
have been replaced with seek(time), current(), and next(), all of
which return a SegmentReference and maintain an internal pointer to
the "current" reference.  Care has been taken to maintain that pointer
during the evict() and fit() operations.  Recent changes to merge()
made sure that the pointer does not need to change during that
operation.

All test updates are related to the SegmentIndex API change, not
changing expectations or behavior.

Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)

Change-Id: I1682dcc2dd625c6e390711538e46d31e6eb6cea8
2020-03-11 18:14:14 +00:00
Álvaro Velad Galván dcf471d85c Calculate approximate segment size based on bandwidth (#2288) 2020-02-17 13:05:38 -08:00
Jacob Trimble c8043f3916 Allow configuring when to fetch prev segment.
We fetch the previous segment in Live streams to combat differences
between the manfiest times and the segment times.  Now this can be
configured so apps with correct manifests can avoid the extra segment
request.

Also, we'll update the buffering state when a segment appends so we
leave the buffering state sooner.

Issue #2291

Change-Id: Id12c8132dc11739e4c8d42cb1f08e6ae7da1a966
2020-02-15 01:52:05 +00:00
Jacob Trimble 011749e95f Standardize argument comments.
This changes the eslint rule to enforce a strict pattern for the
argument comments.  The comment must appear before the argument and
must be /* foo= */.  This still ignores line comments.

Change-Id: I3afb01c65e1088eda13facb3aeeaa7595a2f5aee
2020-01-06 19:40:52 +00:00
Joey Parrish c13830e535 Augment SegmentReference with offset and window
SegmentReference used to have presentationTimeOffset, which,
subtracted from the period start time, was then _added_ to the
timestamps in the segment by MediaSource.

Now, SegmentReference has a timestampOffset field, which is exactly
what MediaSource's timestampOffset field is set to on the SourceBuffer
before this segment is appended.  For DASH, this is periodStart minus
presentationTimeOffset.

This also adds append window start & end times to the
SegmentReference.  Now segments can be appended to SourceBuffers
without reference to the period.

Note that start & end times of the SegmentReference in each segment
index are still relative to the period.  This will change in a
follow-up.

Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)

Change-Id: I9d54eb2b529ec643c9475b8e9d218c3e2e826a26
2019-12-19 11:35:14 -08:00
Joey Parrish 64896d70b0 Use shorter license header
This reflects changes in Google's policy on JavaScript license
headers, which should be smaller to avoid increasing the size of the
binary unnecessarily.

This also updates the company name from "Google, Inc" to "Google LLC".

Change-Id: I3f8b9ed3700b6351f43173d50c94d35c333e82b4
2019-11-22 18:18:36 +00:00
Joey Parrish c395a75b3c Fix exception on adaptation decisions
Because aborting requires knowledge of the new stream, this process
must be done asynchronously.  This makes the abort logic async, and
checks carefully for any stream or operation changes during the
process.

Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)

Change-Id: Ic187676eeca907603efeb0ffa11855b9af2fc5ca
2019-11-07 11:32:58 -08:00
Joey Parrish 0c08793392 Clean up async issues in "lazily create SegmentIndex"
Instead of making many internal methods async to accomodate
createSegmentIndex being called lazily, just call createSegmentIndex
during the update cycle instead.  This greatly simplifies things and
allows me to revert some of the changes I made in the earlier commit.

Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)

Change-Id: I72be8e88f0cf8b04b63d3cda129fa38cef727c0f
2019-11-06 18:50:53 +00:00
Joey Parrish d749c5d156 Performance: lazily create SegmentIndex
In StreamingEngine, rather than wait to enable ABR after indexes have
been created for all streams, create each stream's SegmentIndex
on-demand as needed during playback.  This means ABR can be enabled
much more quickly, and also eliminates some complexity from
StreamingEngine's startup sequence.

This required several test changes, since many of our tests were
accidentally structured to depend on certain operations either being
synchronous or happening early during startup.

Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)

Change-Id: I4bc1d0cdf9022aad14a008accf0aac37c870a83f
2019-11-05 09:40:58 -08:00
Jacob Trimble c014d445a4 Fix Period transitions with embedded captions.
We would incorrectly initialize the embedded captions multiple times
during a Period transition, which caused duplicate cues to be given to
the displayer.  We also wouldn't handle the case when switching between
embedded captions and external text during a Period transition.  This
fixes both cases and adds tests for them.

This also avoids passing an empty cue list to the displayer.

Fixes #2076

Change-Id: I89add3eb86ad8d93644bba14eabd11f98d57bc5e
2019-09-23 22:54:00 +00:00
Jacob Trimble c0e7a9b62a Use callbacks for ManifestGenerator.
This allows us to avoid suppressing the indentation rules and ensures
we have correct indentation.  It also makes it harder to make mistakes
since the variables are only accessible within the callback and you
can't accidentally contaminate another object with an incorrect call.

Closes #1692

Change-Id: Ic38b5cd57a2587dfc8c115ba782656c15565b655
2019-09-04 22:51:12 +00:00
Jacob Trimble bf5547b78c Refactor ArrayBuffer usage in tests.
Change-Id: I27e898a7d3c2d706e265abfc4b9bde88b67f3256
2019-08-21 20:44:36 +00:00
Joey Parrish 7fe97b841b Move fields to SegmentReference
To prepare for flattening out the manifest structure to remove
periods, this change moves initSegmentReference and
presentationTimeOffset fields into the SegmentReference object.  This
way, the segments on either side of a period transition or HLS
discontinuity can have different offsets or init segments, eventually
allowing us to create a single array of SegmentReferences for
multi-period content.

Issue #1339

Change-Id: Ic7eff0483789644881247ecf8044c5fb6a48f0e6
2019-08-01 11:04:36 -07:00
Jacob Trimble fd0dc8a5cc Add utility for looping from 0 to n.
Closes #1518

Change-Id: I865f7a0311516d04ae84532dab873e1aaa31eb24
2019-07-10 21:23:22 +00:00
Jacob Trimble a6b0bb6f8b Remove PromiseMock from StreamingEngine tests.
Issue #1379
Issue #1953

Change-Id: I21cbb436723f3207c707f1596ebb0f8142bab4e4
2019-07-09 11:05:54 -07:00
Joey Parrish 08cec995c9 Replace find/get callbacks with SegmentIndex
This replaces find/get callbacks in Stream with a SegmentIndex.  With
the exception of DASH's SegmentTemplate+duration, all manifests were
already backed by SegmentIndex.  Now, all manifests are backed by
SegmentIndex.  This will simplify Period-flattening, in which all
tracks will be represented by a list of segments, some of which come
from different Periods.

The SegmentIndex in Stream will not be created until
createSegmentIndex is called.  Prior to this change, the find/get
callbacks could be invoked without createSegmentIndex() in some cases
(excluding DASH's SegmentBase), which some lazy tests took advantage
of.  Now that find/get are methods on SegmentIndex, createSegmentIndex
must be called in all cases.  The tests have been updated accordingly.

Making SegmentIndex generation async in all cases exposed some issues
with the parser context being modified in-place between one
Representation and the next.  So the parser now makes a shallow copy
of the context before it is bound into an async callback.

To facilitate updating the SegmentIndex for SegmentTemplate+duration
content, SegmentIndex now has a method to update its list on a timer.
Once per segment duration, the index will be updated to add and remove
SegmentReferences.

The initial expansion of SegmentTemplate+duration will be limited to a
relatively small number of segments, to avoid excessive CPU or memory
consumption.  This defaults to 1000 segments, but is configurable.

Issue #1339

Change-Id: I99c007b1096c3b396d04a729750cd7b743cb899d
2019-07-08 22:22:13 +00:00
Jacob Trimble 60d2f1cc82 Work around MediaSource duration bug.
Fixes #1967

Change-Id: Ie2a41cb17427316ce65cf180507c1fb1f2c6f11a
2019-06-26 20:57:30 +00:00
Jacob Trimble 83de1ad634 Use toBe instead of toEqual for primitives.
This ensures that we get the expected types and that type coercion
doesn't convert between types.  This also ensures we are consistent
in how we check for equality of primitives in tests.

Change-Id: I9f3aacdf25ab1afe5e8d6e4b895b5299ee687d54
2019-06-26 18:57:18 +00:00
Jacob Trimble b235ca4fe7 Favor expect.not.toHaveBeenCalled.
Change-Id: I7009ff69bfca5ef8a38bcdff73a16a02cfa205b1
2019-06-26 18:53:00 +00:00
Jacob Trimble e2ba179201 Favor using toHaveBeenCalledTimes.
This gives better error messages than using toBe() or toEqual() with
the number of calls.

Change-Id: Ice353f1ebcc715da69416da2d983e919597f82d1
2019-06-26 18:52:36 +00:00
Jacob Trimble 2d4904cb75 Add tests for errors during clear buffer.
This error wasn't caught before, but was fixed in a recent CL.  This
adds a test to ensure we don't regress later.

Change-Id: I10e72303c39de82bb9a1f7cb4a6b171c46fdbecd
2019-06-26 17:50:01 +00:00
Jacob Trimble 3da809019b Enable additional ES6 linter rules.
Change-Id: I6861541b27153ba034364a5972a9b086de581cef
2019-06-11 18:35:09 +00:00
Jacob Trimble 7ecce742d2 Misc test ES6 changes.
Issue #1157

Change-Id: I47f537bca5106b4ffca5db3182c8a268d2f3d24a
2019-06-03 22:00:21 +00:00
Jacob Trimble 61d71df219 Convert media tests to ES6.
Issue #1157

Change-Id: I007f5dd43f297ca108cbb2caa7a9118527722350
2019-05-30 19:54:16 +00:00
Joey Parrish 92ef26cf56 Fix StreamingEngine test flake
"StreamingEngine switchVariant/switchTextStream will not clear buffers
if streams have not changed" would fail sometimes with an upgrade to
Jasmine 3 (14/500 runs).  Further investigation revealed that a race
would cause the presentation time to be accessed before it was set,
which led to a segment position of NaN, and a segment reference with
start and end time of NaN.  It is not clear why upgrading Jasmine
caused this race to become more apparent.

This fixes the problem at several levels:
 - An invalid segment position in the ManifestGenerator will cause a
   failed assertion.
 - An uninitialized presentation time in the StreamingEngine unit
   tests, which led to the invalid segment position, will cause a
   failed assertion.
 - The presentation time for the switchVariant test is now initialized
   properly.

After the fix, the test passed in 500/500 complete test runs.

Change-Id: I5c4c52a9e2a89edb61f7d99721be3df840bba30d
2019-05-30 05:39:33 -07:00
Joey Parrish 208c7c55f0 Abort network requests if it won't cause buffering
Rather than only aborting a request if the new request is smaller
(effective when adapting down), abort if the new request will be done
"on time" (effective when adapting up) without causing buffering.

Change-Id: I7572b8bfc566a4f264a5080e4c1bc983f1363ce0
2019-05-15 17:27:37 +00:00
Jacob Trimble f130dffcef Enable eslint indentation rule.
This is a fully automated change.  The linter will fail because the
extra indentation caused line-length errors.  These won't be fixed
automatically.  They are fixed in a follow-up to make this one fully
automated.

Change-Id: I4d8cf9c998985add2bcd24a81c8d65495668c4f3
2019-05-13 22:31:09 +00:00
Jacob Trimble 0dd64074b9 Only allow one statement per line.
With the new style rule, we cannot have two statements on the same line.
So we can no longer have an "if" on a single line and we cannot have
an arrow function with a body on the same line as when it is used.
This is mostly a manual change.

Change-Id: I2285202dd5ecbad764308bc725e6d317ff2ee7f0
2019-05-13 22:11:50 +00:00
Jacob Trimble 984bb6f340 Fix ManifestGenerator indentation.
We use custom indentation for the ManifestGenerator to make the repeated
calls easier to read.  This disables the coming linter rule for these
blocks of code.  This also goes through and unifies the formatting.  The
indentation should be 4 spaces from the left side.

Change-Id: I687e69cea39bded1e9e06bffdcc888970b383fa2
2019-05-13 22:11:37 +00:00
Jacob Trimble 47daf49f31 Use arrow functions for callbacks.
This is an automated change to convert use of "function" functions
to arrow functions.  This doesn't change all uses of bind() that
could be converted.  This also doesn't remove all "function" functions.

Change-Id: I40ac7d086bcef947a1be083359c8fd1d4499a9c3
2019-05-09 16:40:46 +00:00
Jacob Trimble cea3161ce9 Misc fixes for arrow functions.
A follow-up commit will convert "function" functions to arrow functions.
This caused some errors with the compiler, which this change fixes
beforehand.

Change-Id: Iff85b1e1f56b63a38b09f8db9947ed5daf02ddf4
2019-05-08 20:43:20 +00:00
Jacob Trimble c81389741f Prefer const over let.
A coming update to the Google eslint config will require using "const"
over "let".  This makes that one change to isolate the big changes.

Change-Id: I7d0974c3ae15c53cc45a6b07bf9f6586e2d34aca
2019-05-08 09:22:10 -07:00
Theodore Abshire f036c94802 Fix video reloading on audio language change.
Previously, on seek, if any stream was unbuffered, it was considered an
unbuffered seek and every stream was cleared. This was to account for
the possibility that the streams would end up in different periods, and
therefore cause a hang.
However, this meant that changing the audio stream caused the video
stream to be flushed and reloaded pointlessly.
This changes the code to only clear all buffers if a stream has moved
into a different period; if one hasn't, it clears them on a case-by-case
basis.

Closes #1714

Change-Id: I6385e24266834bfc0c6dd2678facc5559affb941
2019-05-08 02:40:48 +00:00
Jacob Trimble 8ec9e19c4a Add tests for progress events and aborts.
Closes #1051

Change-Id: I6d194751c9c248927688783805efe0335fffe312
2019-05-07 18:29:20 +00:00
Jacob Trimble 9ae237cc3c Fix captions being displayed initially.
When the audio and text languages differ, we should display the captions
by default.  This also happens if the app calls setTextTrackVisibility
before calling load.  What happened is the text media state was being
created, but an update wasn't being scheduled.  This meant the text
segments never got appended.  This changes when the update gets
schedules.  This also removes an unnecessary call to set the initial
state during startup.

Issue #1696
Closes #1879

Change-Id: If3a1b9e2889fc0e487da0e7276ca837636bf2e54
2019-05-03 15:58:08 +00:00
Michelle Zhuo 40f9113bb2 Abort requests when network downgrading
When the network becomes slow, we check if stopping the current request
and download the content with lower resolution is faster. If so, abort
the current request and start a new one.

Issue #1051

Change-Id: I588e524469432e362361d1cfbde6cd45c2009959
2019-05-01 20:18:16 +00:00
Aaron Vaage 1776ea6e55 Rename StreamingEngine.init to StreamingEngine.start
The init method on streaming engine is responsible for initializing
streaming engine but it also starts the streaming process. In the
greater scheme of things, this is what starts playback.

To help communicate the full effect of what this one method does, this
changes its name to be "start" which helps show that it is starting a
process, not just initializing.

Change-Id: Ieceecce85917d97277782f41fd376fc6f97eaac9
2019-03-29 00:25:56 +00:00
Aaron Vaage edd7394ee0 Refactor StreamingEngine to not use Playhead directly
In streaming engine, we would use playhead to get the current
presentation time. Playhead was provided via the player
interface (defined by streaming engine).

Since streaming engine only needed to know what the presentation
time is, this changes the player interface to require a function
to get the presentation time rather than the playhead.

The general theme of this move is to help define the interface
in terms of needs and not the means in which they are fulfilled.

Change-Id: I442d54f08b650f22b9273a191d5a3a57af37b5bf
2019-01-22 22:00:07 +00:00
Aaron Vaage 846c15cdb9 Rename getActive* to getBuffering*
To make it easier to understand the context of the streams
and periods returned by StreamingEngine, "getActive" is
renamed to "getBuffering".

Change-Id: I99aec589bd4d736b170fa2197e5097ff33c0fc82
2019-01-15 15:24:18 -08:00
Jacob Trimble c3ce160217 Consolidate default configs in tests.
Instead of duplicating the default configuration values in each test,
this now uses the default configuration methods.

Change-Id: Ifd2ab349db7903a2acb0d06fed4bd0ccd5050b35
2018-12-27 18:00:55 +00:00