rx-player 4.5.0-dev.2026033100 → 4.5.0-dev.2026041501
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -5
- package/VERSION +1 -1
- package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
- package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
- package/dist/commonjs/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
- package/dist/commonjs/__GENERATED_CODE/embedded_worker.js +1 -1
- package/dist/commonjs/compat/can_patch_out_pssh.d.ts +42 -0
- package/dist/commonjs/compat/can_patch_out_pssh.d.ts.map +1 -0
- package/dist/commonjs/compat/can_patch_out_pssh.js +53 -0
- package/dist/commonjs/compat/env_detector.d.ts +2 -0
- package/dist/commonjs/compat/env_detector.d.ts.map +1 -1
- package/dist/commonjs/compat/env_detector.js +5 -0
- package/dist/commonjs/core/adaptive/network_analyzer.d.ts +1 -2
- package/dist/commonjs/core/adaptive/network_analyzer.d.ts.map +1 -1
- package/dist/commonjs/core/adaptive/network_analyzer.js +3 -3
- package/dist/commonjs/core/adaptive/utils/representation_score_calculator.js +2 -2
- package/dist/commonjs/core/cmcd/cmcd_data_builder.d.ts.map +1 -1
- package/dist/commonjs/core/cmcd/cmcd_data_builder.js +9 -3
- package/dist/commonjs/core/entry/content_preparer.d.ts.map +1 -1
- package/dist/commonjs/core/entry/content_preparer.js +5 -7
- package/dist/commonjs/core/entry/core_entry.d.ts.map +1 -1
- package/dist/commonjs/core/entry/core_entry.js +6 -2
- package/dist/commonjs/core/entry/core_text_displayer_interface.js +3 -3
- package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.d.ts.map +1 -1
- package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.js +12 -0
- package/dist/commonjs/core/fetchers/thumbnails/thumbnail_fetcher.js +1 -1
- package/dist/commonjs/core/fetchers/utils/schedule_request.d.ts.map +1 -1
- package/dist/commonjs/core/fetchers/utils/schedule_request.js +4 -3
- package/dist/commonjs/core/segment_sinks/garbage_collector.d.ts +0 -2
- package/dist/commonjs/core/segment_sinks/garbage_collector.d.ts.map +1 -1
- package/dist/commonjs/core/segment_sinks/garbage_collector.js +0 -3
- package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.d.ts +1 -1
- package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.d.ts.map +1 -1
- package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.js +2 -2
- package/dist/commonjs/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
- package/dist/commonjs/core/stream/adaptation/adaptation_stream.js +6 -6
- package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
- package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +37 -40
- package/dist/commonjs/default_config.d.ts +5 -0
- package/dist/commonjs/default_config.d.ts.map +1 -1
- package/dist/commonjs/default_config.js +5 -0
- package/dist/commonjs/main_thread/api/public_api.d.ts.map +1 -1
- package/dist/commonjs/main_thread/api/public_api.js +23 -16
- package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/content_decryptor.js +4 -1
- package/dist/commonjs/main_thread/decrypt/session_events_listener.js +1 -1
- package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts +2 -0
- package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/set_server_certificate.js +4 -0
- package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts +0 -8
- package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
- package/dist/commonjs/main_thread/init/media_source_content_initializer.js +58 -50
- package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +35 -5
- package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
- package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +60 -19
- package/dist/commonjs/main_thread/render_thumbnail.d.ts.map +1 -1
- package/dist/commonjs/main_thread/render_thumbnail.js +4 -0
- package/dist/commonjs/main_thread/tracks_store/media_element_tracks_store.d.ts.map +1 -1
- package/dist/commonjs/main_thread/tracks_store/media_element_tracks_store.js +1 -0
- package/dist/commonjs/main_thread/tracks_store/tracks_store.d.ts +1 -1
- package/dist/commonjs/main_thread/tracks_store/tracks_store.js +1 -1
- package/dist/{es2017/parsers/containers/isobmff/take_pssh_out.d.ts → commonjs/parsers/containers/isobmff/extract_pssh.d.ts} +6 -4
- package/dist/commonjs/parsers/containers/isobmff/extract_pssh.d.ts.map +1 -0
- package/dist/commonjs/parsers/containers/isobmff/{take_pssh_out.js → extract_pssh.js} +22 -17
- package/dist/commonjs/parsers/containers/isobmff/index.d.ts +2 -2
- package/dist/commonjs/parsers/containers/isobmff/index.d.ts.map +1 -1
- package/dist/commonjs/parsers/containers/isobmff/index.js +4 -4
- package/dist/commonjs/playback_observer/core_playback_observer.d.ts +4 -4
- package/dist/commonjs/playback_observer/core_playback_observer.d.ts.map +1 -1
- package/dist/commonjs/playback_observer/media_element_playback_observer.d.ts +1 -2
- package/dist/commonjs/playback_observer/media_element_playback_observer.d.ts.map +1 -1
- package/dist/commonjs/transports/dash/segment_parser.js +1 -1
- package/dist/commonjs/transports/local/segment_parser.js +1 -1
- package/dist/commonjs/utils/test-utils.d.ts +30 -0
- package/dist/commonjs/utils/test-utils.d.ts.map +1 -0
- package/dist/commonjs/utils/test-utils.js +79 -0
- package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
- package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
- package/dist/es2017/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
- package/dist/es2017/__GENERATED_CODE/embedded_worker.js +1 -1
- package/dist/es2017/compat/can_patch_out_pssh.d.ts +42 -0
- package/dist/es2017/compat/can_patch_out_pssh.d.ts.map +1 -0
- package/dist/es2017/compat/can_patch_out_pssh.js +50 -0
- package/dist/es2017/compat/env_detector.d.ts +2 -0
- package/dist/es2017/compat/env_detector.d.ts.map +1 -1
- package/dist/es2017/compat/env_detector.js +5 -0
- package/dist/es2017/core/adaptive/network_analyzer.d.ts +1 -2
- package/dist/es2017/core/adaptive/network_analyzer.d.ts.map +1 -1
- package/dist/es2017/core/adaptive/network_analyzer.js +3 -3
- package/dist/es2017/core/adaptive/utils/representation_score_calculator.js +2 -2
- package/dist/es2017/core/cmcd/cmcd_data_builder.d.ts.map +1 -1
- package/dist/es2017/core/cmcd/cmcd_data_builder.js +9 -3
- package/dist/es2017/core/entry/content_preparer.d.ts.map +1 -1
- package/dist/es2017/core/entry/content_preparer.js +3 -5
- package/dist/es2017/core/entry/core_entry.d.ts.map +1 -1
- package/dist/es2017/core/entry/core_entry.js +6 -2
- package/dist/es2017/core/entry/core_text_displayer_interface.js +3 -3
- package/dist/es2017/core/fetchers/manifest/manifest_fetcher.d.ts.map +1 -1
- package/dist/es2017/core/fetchers/manifest/manifest_fetcher.js +12 -0
- package/dist/es2017/core/fetchers/thumbnails/thumbnail_fetcher.js +1 -1
- package/dist/es2017/core/fetchers/utils/schedule_request.d.ts.map +1 -1
- package/dist/es2017/core/fetchers/utils/schedule_request.js +2 -3
- package/dist/es2017/core/segment_sinks/garbage_collector.d.ts +0 -2
- package/dist/es2017/core/segment_sinks/garbage_collector.d.ts.map +1 -1
- package/dist/es2017/core/segment_sinks/garbage_collector.js +0 -3
- package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.d.ts +1 -1
- package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.d.ts.map +1 -1
- package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.js +2 -2
- package/dist/es2017/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
- package/dist/es2017/core/stream/adaptation/adaptation_stream.js +6 -6
- package/dist/es2017/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
- package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +40 -39
- package/dist/es2017/default_config.d.ts +5 -0
- package/dist/es2017/default_config.d.ts.map +1 -1
- package/dist/es2017/default_config.js +5 -0
- package/dist/es2017/main_thread/api/public_api.d.ts.map +1 -1
- package/dist/es2017/main_thread/api/public_api.js +20 -13
- package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/content_decryptor.js +4 -1
- package/dist/es2017/main_thread/decrypt/session_events_listener.js +1 -1
- package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts +2 -0
- package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/set_server_certificate.js +4 -0
- package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts +0 -8
- package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
- package/dist/es2017/main_thread/init/media_source_content_initializer.js +58 -50
- package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +35 -5
- package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
- package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +60 -19
- package/dist/es2017/main_thread/render_thumbnail.d.ts.map +1 -1
- package/dist/es2017/main_thread/render_thumbnail.js +4 -0
- package/dist/es2017/main_thread/tracks_store/media_element_tracks_store.d.ts.map +1 -1
- package/dist/es2017/main_thread/tracks_store/media_element_tracks_store.js +1 -0
- package/dist/es2017/main_thread/tracks_store/tracks_store.d.ts +1 -1
- package/dist/es2017/main_thread/tracks_store/tracks_store.js +1 -1
- package/dist/{commonjs/parsers/containers/isobmff/take_pssh_out.d.ts → es2017/parsers/containers/isobmff/extract_pssh.d.ts} +6 -4
- package/dist/es2017/parsers/containers/isobmff/extract_pssh.d.ts.map +1 -0
- package/dist/es2017/parsers/containers/isobmff/{take_pssh_out.js → extract_pssh.js} +21 -16
- package/dist/es2017/parsers/containers/isobmff/index.d.ts +2 -2
- package/dist/es2017/parsers/containers/isobmff/index.d.ts.map +1 -1
- package/dist/es2017/parsers/containers/isobmff/index.js +2 -2
- package/dist/es2017/playback_observer/core_playback_observer.d.ts +4 -4
- package/dist/es2017/playback_observer/core_playback_observer.d.ts.map +1 -1
- package/dist/es2017/playback_observer/media_element_playback_observer.d.ts +1 -2
- package/dist/es2017/playback_observer/media_element_playback_observer.d.ts.map +1 -1
- package/dist/es2017/transports/dash/segment_parser.js +2 -2
- package/dist/es2017/transports/local/segment_parser.js +2 -2
- package/dist/es2017/utils/test-utils.d.ts +30 -0
- package/dist/es2017/utils/test-utils.d.ts.map +1 -0
- package/dist/es2017/utils/test-utils.js +36 -0
- package/dist/mpd-parser.wasm +0 -0
- package/dist/worker.js +6 -6
- package/package.json +4 -2
- package/src/README.md +7 -7
- package/src/__GENERATED_CODE/embedded_dash_wasm.ts +1 -1
- package/src/__GENERATED_CODE/embedded_worker.ts +1 -1
- package/src/compat/__tests__/can_patch_out_pssh.test.ts +40 -0
- package/src/compat/can_patch_out_pssh.ts +53 -0
- package/src/compat/env_detector.ts +4 -0
- package/src/core/README.md +1 -1
- package/src/core/adaptive/README.md +3 -3
- package/src/core/adaptive/__tests__/adaptive_representation_selector.test.ts +181 -110
- package/src/core/adaptive/__tests__/guess_based_chooser.test.ts +229 -123
- package/src/core/adaptive/__tests__/mocks.ts +100 -0
- package/src/core/adaptive/__tests__/network_analyzer.test.ts +152 -59
- package/src/core/adaptive/network_analyzer.ts +4 -4
- package/src/core/adaptive/utils/__tests__/filter_by_bitrate.test.ts +11 -19
- package/src/core/adaptive/utils/__tests__/filter_by_resolution.test.ts +12 -12
- package/src/core/adaptive/utils/__tests__/last_estimate_storage.test.ts +25 -12
- package/src/core/adaptive/utils/__tests__/pending_requests_store.test.ts +13 -9
- package/src/core/adaptive/utils/__tests__/representation_score_calculator.test.ts +11 -11
- package/src/core/adaptive/utils/__tests__/select_optimal_representation.test.ts +13 -23
- package/src/core/adaptive/utils/representation_score_calculator.ts +2 -2
- package/src/core/cmcd/__tests__/cmcd_data_builder.test.ts +60 -15
- package/src/core/cmcd/cmcd_data_builder.ts +9 -3
- package/src/core/entry/README.md +2 -2
- package/src/core/entry/__tests__/core_text_displayer_interface.test.ts +20 -0
- package/src/core/entry/content_preparer.ts +2 -5
- package/src/core/entry/core_entry.ts +6 -2
- package/src/core/entry/core_text_displayer_interface.ts +3 -3
- package/src/core/fetchers/manifest/__tests__/manifest_fetcher.test.ts +52 -3
- package/src/core/fetchers/manifest/manifest_fetcher.ts +12 -0
- package/src/core/fetchers/thumbnails/__tests__/thumbnail_fetcher.test.ts +70 -0
- package/src/core/fetchers/thumbnails/thumbnail_fetcher.ts +1 -1
- package/src/core/fetchers/utils/schedule_request.ts +5 -3
- package/src/core/segment_sinks/__tests__/garbage_collector.test.ts +434 -0
- package/src/core/segment_sinks/__tests__/mocks.ts +49 -0
- package/src/core/segment_sinks/garbage_collector.ts +0 -3
- package/src/core/segment_sinks/implementations/text/__tests__/text_segment_sink.test.ts +177 -0
- package/src/core/segment_sinks/implementations/text/text_segment_sink.ts +2 -2
- package/src/core/segment_sinks/inventory/__tests__/buffered_history.test.ts +215 -0
- package/src/core/segment_sinks/inventory/__tests__/segment_inventory.test.ts +448 -0
- package/src/core/stream/adaptation/__tests__/adaptation_stream.test.ts +973 -0
- package/src/core/stream/adaptation/__tests__/get_representations_switch_strategy.test.ts +283 -374
- package/src/core/stream/adaptation/adaptation_stream.ts +6 -8
- package/src/core/stream/orchestrator/README.md +4 -4
- package/src/core/stream/orchestrator/__tests__/stream_orchestrator.test.ts +707 -0
- package/src/core/stream/orchestrator/stream_orchestrator.ts +41 -46
- package/src/core/stream/period/utils/__tests__/get_adaptation_switch_strategy.test.ts +290 -220
- package/src/core/stream/representation/__tests__/encryption_data_notifier.test.ts +93 -63
- package/src/core/stream/representation/utils/__tests__/append_segment_to_buffer.test.ts +106 -63
- package/src/core/stream/representation/utils/__tests__/check_for_discontinuity.test.ts +179 -204
- package/src/core/stream/representation/utils/__tests__/get_segment_priority.test.ts +7 -7
- package/src/core/stream/representation/utils/__tests__/push_init_segment.test.ts +103 -60
- package/src/core/stream/representation/utils/__tests__/push_media_segment.test.ts +231 -165
- package/src/default_config.ts +6 -0
- package/src/experimental/README.md +1 -1
- package/src/features/README.md +3 -3
- package/src/main_thread/api/README.md +6 -7
- package/src/main_thread/api/public_api.ts +16 -10
- package/src/main_thread/decrypt/README.md +4 -4
- package/src/main_thread/decrypt/__tests__/__global__/content_decryptor.test.ts +135 -0
- package/src/main_thread/decrypt/__tests__/__global__/get_license.test.ts +70 -0
- package/src/main_thread/decrypt/__tests__/__global__/server_certificate.test.ts +44 -0
- package/src/main_thread/decrypt/__tests__/__global__/utils.ts +2 -2
- package/src/main_thread/decrypt/content_decryptor.ts +6 -1
- package/src/main_thread/decrypt/session_events_listener.ts +1 -1
- package/src/main_thread/decrypt/set_server_certificate.ts +5 -0
- package/src/main_thread/init/media_source_content_initializer.ts +69 -55
- package/src/main_thread/init/utils/__tests__/stream_events_emitter.test.ts +175 -0
- package/src/main_thread/init/utils/stream_events_emitter/stream_events_emitter.ts +90 -26
- package/src/main_thread/render_thumbnail.ts +4 -0
- package/src/main_thread/tracks_store/README.md +12 -0
- package/src/main_thread/tracks_store/__tests__/media_element_tracks_store.test.ts +25 -18
- package/src/main_thread/tracks_store/media_element_tracks_store.ts +1 -0
- package/src/main_thread/tracks_store/tracks_store.ts +1 -1
- package/src/manifest/classes/__tests__/mocks.ts +202 -0
- package/src/parsers/containers/isobmff/__tests__/extract_pssh.test.ts +199 -0
- package/src/parsers/containers/isobmff/{take_pssh_out.ts → extract_pssh.ts} +21 -17
- package/src/parsers/containers/isobmff/index.ts +2 -2
- package/src/parsers/manifest/dash/wasm-parser/README.md +9 -9
- package/src/playback_observer/__tests__/mocks.ts +152 -0
- package/src/playback_observer/core_playback_observer.ts +4 -4
- package/src/playback_observer/media_element_playback_observer.ts +1 -1
- package/src/tools/README.md +2 -2
- package/src/transports/README.md +5 -5
- package/src/transports/dash/segment_parser.ts +2 -2
- package/src/transports/local/segment_parser.ts +2 -2
- package/src/transports/metaplaylist/README.md +4 -4
- package/src/utils/README.md +3 -3
- package/src/utils/test-utils.ts +50 -0
- package/dist/commonjs/core/entry/synchronize_sinks_on_observation.d.ts +0 -11
- package/dist/commonjs/core/entry/synchronize_sinks_on_observation.d.ts.map +0 -1
- package/dist/commonjs/core/entry/synchronize_sinks_on_observation.js +0 -20
- package/dist/commonjs/parsers/containers/isobmff/take_pssh_out.d.ts.map +0 -1
- package/dist/es2017/core/entry/synchronize_sinks_on_observation.d.ts +0 -11
- package/dist/es2017/core/entry/synchronize_sinks_on_observation.d.ts.map +0 -1
- package/dist/es2017/core/entry/synchronize_sinks_on_observation.js +0 -17
- package/dist/es2017/parsers/containers/isobmff/take_pssh_out.d.ts.map +0 -1
- package/src/core/adaptive/utils/__tests__/bandwith_estimator.test.ts +0 -117
- package/src/core/entry/synchronize_sinks_on_observation.ts +0 -22
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import type { IRepresentation } from "../../../manifest";
|
|
3
|
+
import {
|
|
4
|
+
DummyRepresentation,
|
|
5
|
+
DummyAdaptation,
|
|
6
|
+
DummyPeriod,
|
|
7
|
+
DummyManifest,
|
|
8
|
+
createSegment,
|
|
9
|
+
} from "../../../manifest/classes/__tests__/mocks";
|
|
10
|
+
import noop from "../../../utils/noop";
|
|
11
|
+
import { makeMockedClass } from "../../../utils/test-utils";
|
|
3
12
|
import GuessBasedChooser from "../guess_based_chooser";
|
|
13
|
+
import type LastEstimateStorage from "../utils/last_estimate_storage";
|
|
4
14
|
import { ABRAlgorithmType } from "../utils/last_estimate_storage";
|
|
5
15
|
import type { IRequestInfo } from "../utils/pending_requests_store";
|
|
6
16
|
import type { IRepresentationMaintainabilityScore } from "../utils/representation_score_calculator";
|
|
17
|
+
import type RepresentationScoreCalculator from "../utils/representation_score_calculator";
|
|
7
18
|
import { ScoreConfidenceLevel } from "../utils/representation_score_calculator";
|
|
8
19
|
|
|
9
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
10
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
11
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
12
|
-
|
|
13
20
|
const mocks = vi.hoisted(() => ({
|
|
14
21
|
estimateRequestBandwidth: vi.fn(),
|
|
15
22
|
getMonotonicTimeStamp: vi.fn(),
|
|
@@ -21,26 +28,18 @@ vi.mock("../../../log", () => ({
|
|
|
21
28
|
error: vi.fn(),
|
|
22
29
|
},
|
|
23
30
|
}));
|
|
24
|
-
|
|
25
|
-
vi.mock("../../../utils/array_find_index", () => ({
|
|
26
|
-
// eslint-disable-next-line no-restricted-properties
|
|
27
|
-
default: vi.fn((arr, predicate) => arr.findIndex(predicate)),
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
31
|
vi.mock("../../../utils/monotonic_timestamp", () => ({
|
|
31
32
|
default: mocks.getMonotonicTimeStamp,
|
|
32
33
|
}));
|
|
33
|
-
|
|
34
34
|
vi.mock("../network_analyzer", () => ({
|
|
35
35
|
estimateRequestBandwidth: mocks.estimateRequestBandwidth,
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
|
-
// Helper functions
|
|
39
38
|
function createRepresentation(id: string, bitrate: number): IRepresentation {
|
|
40
|
-
return {
|
|
39
|
+
return new DummyRepresentation({
|
|
41
40
|
id,
|
|
42
41
|
bitrate,
|
|
43
|
-
}
|
|
42
|
+
});
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
function createScoreData(
|
|
@@ -58,41 +57,53 @@ function createRequest(
|
|
|
58
57
|
): IRequestInfo {
|
|
59
58
|
return {
|
|
60
59
|
content: {
|
|
61
|
-
representation: {
|
|
62
|
-
|
|
60
|
+
representation: new DummyRepresentation({
|
|
61
|
+
id: representationId,
|
|
62
|
+
}),
|
|
63
|
+
segment: createSegment({
|
|
63
64
|
duration: segmentDuration,
|
|
64
65
|
isInit,
|
|
65
|
-
},
|
|
66
|
+
}),
|
|
67
|
+
adaptation: new DummyAdaptation(),
|
|
68
|
+
period: new DummyPeriod(),
|
|
69
|
+
manifest: new DummyManifest(),
|
|
66
70
|
},
|
|
67
71
|
requestTimestamp,
|
|
68
|
-
|
|
72
|
+
progress: [],
|
|
73
|
+
};
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
const DummyScoreCalculator = makeMockedClass<RepresentationScoreCalculator>(
|
|
77
|
+
{
|
|
78
|
+
addSample: noop,
|
|
79
|
+
getEstimate: () => createScoreData(1, ScoreConfidenceLevel.LOW),
|
|
80
|
+
getLastStableRepresentation: () => null,
|
|
81
|
+
},
|
|
82
|
+
{},
|
|
83
|
+
);
|
|
84
|
+
const DummyLastEstimateStorage = makeMockedClass<LastEstimateStorage>(
|
|
85
|
+
{
|
|
86
|
+
update: noop,
|
|
87
|
+
},
|
|
88
|
+
{ bandwidth: undefined, representation: null, algorithmType: ABRAlgorithmType.None },
|
|
89
|
+
);
|
|
90
|
+
|
|
71
91
|
describe("GuessBasedChooser", () => {
|
|
72
|
-
let mockScoreCalculator:
|
|
73
|
-
let
|
|
74
|
-
|
|
92
|
+
let mockScoreCalculator: RepresentationScoreCalculator;
|
|
93
|
+
let mockLastEstimateStorage: LastEstimateStorage;
|
|
94
|
+
|
|
95
|
+
const representations = [
|
|
96
|
+
createRepresentation("rep-1", 100000),
|
|
97
|
+
createRepresentation("rep-2", 500000),
|
|
98
|
+
createRepresentation("rep-3", 1000000),
|
|
99
|
+
createRepresentation("rep-4", 2000000),
|
|
100
|
+
createRepresentation("rep-5", 3000000),
|
|
101
|
+
];
|
|
75
102
|
|
|
76
103
|
beforeEach(() => {
|
|
77
104
|
mocks.getMonotonicTimeStamp.mockReturnValue(10000);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
representations = [
|
|
81
|
-
createRepresentation("rep-1", 100000),
|
|
82
|
-
createRepresentation("rep-2", 500000),
|
|
83
|
-
createRepresentation("rep-3", 1000000),
|
|
84
|
-
createRepresentation("rep-4", 2000000),
|
|
85
|
-
createRepresentation("rep-5", 3000000),
|
|
86
|
-
];
|
|
87
|
-
|
|
88
|
-
mockScoreCalculator = {
|
|
89
|
-
getEstimate: vi.fn(),
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
mockPrevEstimate = {
|
|
93
|
-
representation: null,
|
|
94
|
-
algorithmType: ABRAlgorithmType.GuessBased,
|
|
95
|
-
};
|
|
105
|
+
mockScoreCalculator = new DummyScoreCalculator();
|
|
106
|
+
mockLastEstimateStorage = new DummyLastEstimateStorage();
|
|
96
107
|
});
|
|
97
108
|
|
|
98
109
|
afterEach(() => {
|
|
@@ -101,7 +112,7 @@ describe("GuessBasedChooser", () => {
|
|
|
101
112
|
|
|
102
113
|
describe("constructor", () => {
|
|
103
114
|
it("should initialize with correct default values", () => {
|
|
104
|
-
const chooser = new GuessBasedChooser(mockScoreCalculator,
|
|
115
|
+
const chooser = new GuessBasedChooser(mockScoreCalculator, mockLastEstimateStorage);
|
|
105
116
|
expect(chooser).toBeDefined();
|
|
106
117
|
});
|
|
107
118
|
});
|
|
@@ -109,8 +120,11 @@ describe("GuessBasedChooser", () => {
|
|
|
109
120
|
describe("getGuess", () => {
|
|
110
121
|
describe("when last chosen representation is null", () => {
|
|
111
122
|
it("should return null - nothing to base guess on", () => {
|
|
112
|
-
|
|
113
|
-
const chooser = new GuessBasedChooser(
|
|
123
|
+
mockLastEstimateStorage.representation = null;
|
|
124
|
+
const chooser = new GuessBasedChooser(
|
|
125
|
+
mockScoreCalculator,
|
|
126
|
+
mockLastEstimateStorage,
|
|
127
|
+
);
|
|
114
128
|
|
|
115
129
|
const result = chooser.getGuess(
|
|
116
130
|
representations,
|
|
@@ -126,10 +140,13 @@ describe("GuessBasedChooser", () => {
|
|
|
126
140
|
|
|
127
141
|
describe("when incomingBestBitrate > lastChosenRep.bitrate", () => {
|
|
128
142
|
it("should return null - ABR estimates are already superior", () => {
|
|
129
|
-
|
|
130
|
-
|
|
143
|
+
mockLastEstimateStorage.representation = representations[1]; // 500000
|
|
144
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
131
145
|
|
|
132
|
-
const chooser = new GuessBasedChooser(
|
|
146
|
+
const chooser = new GuessBasedChooser(
|
|
147
|
+
mockScoreCalculator,
|
|
148
|
+
mockLastEstimateStorage,
|
|
149
|
+
);
|
|
133
150
|
|
|
134
151
|
const result = chooser.getGuess(
|
|
135
152
|
representations,
|
|
@@ -143,10 +160,13 @@ describe("GuessBasedChooser", () => {
|
|
|
143
160
|
});
|
|
144
161
|
|
|
145
162
|
it("should reset consecutive wrong guesses when algorithm was GuessBased", () => {
|
|
146
|
-
|
|
147
|
-
|
|
163
|
+
mockLastEstimateStorage.representation = representations[1];
|
|
164
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
148
165
|
|
|
149
|
-
const chooser = new GuessBasedChooser(
|
|
166
|
+
const chooser = new GuessBasedChooser(
|
|
167
|
+
mockScoreCalculator,
|
|
168
|
+
mockLastEstimateStorage,
|
|
169
|
+
);
|
|
150
170
|
|
|
151
171
|
// First call should reset counter
|
|
152
172
|
chooser.getGuess(
|
|
@@ -172,14 +192,17 @@ describe("GuessBasedChooser", () => {
|
|
|
172
192
|
|
|
173
193
|
describe("when not in guessing mode yet", () => {
|
|
174
194
|
beforeEach(() => {
|
|
175
|
-
|
|
176
|
-
|
|
195
|
+
mockLastEstimateStorage.representation = representations[1];
|
|
196
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
177
197
|
});
|
|
178
198
|
|
|
179
199
|
it("should return null when score data is undefined", () => {
|
|
180
|
-
mockScoreCalculator
|
|
200
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(undefined);
|
|
181
201
|
|
|
182
|
-
const chooser = new GuessBasedChooser(
|
|
202
|
+
const chooser = new GuessBasedChooser(
|
|
203
|
+
mockScoreCalculator,
|
|
204
|
+
mockLastEstimateStorage,
|
|
205
|
+
);
|
|
183
206
|
|
|
184
207
|
const result = chooser.getGuess(
|
|
185
208
|
representations,
|
|
@@ -193,11 +216,13 @@ describe("GuessBasedChooser", () => {
|
|
|
193
216
|
});
|
|
194
217
|
|
|
195
218
|
it("should return next representation when conditions allow guessing higher", () => {
|
|
196
|
-
mockScoreCalculator
|
|
219
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
197
220
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
198
221
|
);
|
|
199
|
-
|
|
200
|
-
|
|
222
|
+
const chooser = new GuessBasedChooser(
|
|
223
|
+
mockScoreCalculator,
|
|
224
|
+
mockLastEstimateStorage,
|
|
225
|
+
);
|
|
201
226
|
|
|
202
227
|
const result = chooser.getGuess(
|
|
203
228
|
representations,
|
|
@@ -211,11 +236,14 @@ describe("GuessBasedChooser", () => {
|
|
|
211
236
|
});
|
|
212
237
|
|
|
213
238
|
it("should return null when buffer gap is too low to guess higher", () => {
|
|
214
|
-
mockScoreCalculator
|
|
239
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
215
240
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
216
241
|
);
|
|
217
242
|
|
|
218
|
-
const chooser = new GuessBasedChooser(
|
|
243
|
+
const chooser = new GuessBasedChooser(
|
|
244
|
+
mockScoreCalculator,
|
|
245
|
+
mockLastEstimateStorage,
|
|
246
|
+
);
|
|
219
247
|
|
|
220
248
|
const result = chooser.getGuess(
|
|
221
249
|
representations,
|
|
@@ -229,11 +257,14 @@ describe("GuessBasedChooser", () => {
|
|
|
229
257
|
});
|
|
230
258
|
|
|
231
259
|
it("should return null when confidence level is not HIGH", () => {
|
|
232
|
-
mockScoreCalculator
|
|
260
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
233
261
|
createScoreData(1.5, ScoreConfidenceLevel.LOW),
|
|
234
262
|
);
|
|
235
263
|
|
|
236
|
-
const chooser = new GuessBasedChooser(
|
|
264
|
+
const chooser = new GuessBasedChooser(
|
|
265
|
+
mockScoreCalculator,
|
|
266
|
+
mockLastEstimateStorage,
|
|
267
|
+
);
|
|
237
268
|
|
|
238
269
|
const result = chooser.getGuess(
|
|
239
270
|
representations,
|
|
@@ -247,11 +278,14 @@ describe("GuessBasedChooser", () => {
|
|
|
247
278
|
});
|
|
248
279
|
|
|
249
280
|
it("should return null when score/speed ratio is too low", () => {
|
|
250
|
-
mockScoreCalculator
|
|
281
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
251
282
|
createScoreData(1.005, ScoreConfidenceLevel.HIGH),
|
|
252
283
|
);
|
|
253
284
|
|
|
254
|
-
const chooser = new GuessBasedChooser(
|
|
285
|
+
const chooser = new GuessBasedChooser(
|
|
286
|
+
mockScoreCalculator,
|
|
287
|
+
mockLastEstimateStorage,
|
|
288
|
+
);
|
|
255
289
|
|
|
256
290
|
const result = chooser.getGuess(
|
|
257
291
|
representations,
|
|
@@ -265,11 +299,14 @@ describe("GuessBasedChooser", () => {
|
|
|
265
299
|
});
|
|
266
300
|
|
|
267
301
|
it("should account for playback speed when checking score", () => {
|
|
268
|
-
mockScoreCalculator
|
|
302
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
269
303
|
createScoreData(2.0, ScoreConfidenceLevel.HIGH),
|
|
270
304
|
);
|
|
271
305
|
|
|
272
|
-
const chooser = new GuessBasedChooser(
|
|
306
|
+
const chooser = new GuessBasedChooser(
|
|
307
|
+
mockScoreCalculator,
|
|
308
|
+
mockLastEstimateStorage,
|
|
309
|
+
);
|
|
273
310
|
|
|
274
311
|
const result = chooser.getGuess(
|
|
275
312
|
representations,
|
|
@@ -283,11 +320,14 @@ describe("GuessBasedChooser", () => {
|
|
|
283
320
|
});
|
|
284
321
|
|
|
285
322
|
it("should return null when already at highest representation", () => {
|
|
286
|
-
mockScoreCalculator
|
|
323
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
287
324
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
288
325
|
);
|
|
289
326
|
|
|
290
|
-
const chooser = new GuessBasedChooser(
|
|
327
|
+
const chooser = new GuessBasedChooser(
|
|
328
|
+
mockScoreCalculator,
|
|
329
|
+
mockLastEstimateStorage,
|
|
330
|
+
);
|
|
291
331
|
|
|
292
332
|
const result = chooser.getGuess(
|
|
293
333
|
representations,
|
|
@@ -303,16 +343,19 @@ describe("GuessBasedChooser", () => {
|
|
|
303
343
|
|
|
304
344
|
describe("when already in guessing mode", () => {
|
|
305
345
|
beforeEach(() => {
|
|
306
|
-
|
|
307
|
-
|
|
346
|
+
mockLastEstimateStorage.representation = representations[2]; // 1000000
|
|
347
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
308
348
|
});
|
|
309
349
|
|
|
310
350
|
it("should take higher guess when conditions are met", () => {
|
|
311
|
-
mockScoreCalculator
|
|
351
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
312
352
|
createScoreData(2.0, ScoreConfidenceLevel.HIGH),
|
|
313
353
|
);
|
|
314
354
|
|
|
315
|
-
const chooser = new GuessBasedChooser(
|
|
355
|
+
const chooser = new GuessBasedChooser(
|
|
356
|
+
mockScoreCalculator,
|
|
357
|
+
mockLastEstimateStorage,
|
|
358
|
+
);
|
|
316
359
|
|
|
317
360
|
const result = chooser.getGuess(
|
|
318
361
|
representations,
|
|
@@ -325,12 +368,15 @@ describe("GuessBasedChooser", () => {
|
|
|
325
368
|
});
|
|
326
369
|
|
|
327
370
|
it("should take same guess when conditions are met with highest guess", () => {
|
|
328
|
-
|
|
329
|
-
mockScoreCalculator
|
|
371
|
+
mockLastEstimateStorage.representation = representations[4];
|
|
372
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
330
373
|
createScoreData(2.0, ScoreConfidenceLevel.HIGH),
|
|
331
374
|
);
|
|
332
375
|
|
|
333
|
-
const chooser = new GuessBasedChooser(
|
|
376
|
+
const chooser = new GuessBasedChooser(
|
|
377
|
+
mockScoreCalculator,
|
|
378
|
+
mockLastEstimateStorage,
|
|
379
|
+
);
|
|
334
380
|
|
|
335
381
|
const result = chooser.getGuess(
|
|
336
382
|
representations,
|
|
@@ -343,11 +389,14 @@ describe("GuessBasedChooser", () => {
|
|
|
343
389
|
});
|
|
344
390
|
|
|
345
391
|
it("should return last chosen representation when current differs", () => {
|
|
346
|
-
mockScoreCalculator
|
|
392
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
347
393
|
createScoreData(1.2, ScoreConfidenceLevel.HIGH),
|
|
348
394
|
);
|
|
349
395
|
|
|
350
|
-
const chooser = new GuessBasedChooser(
|
|
396
|
+
const chooser = new GuessBasedChooser(
|
|
397
|
+
mockScoreCalculator,
|
|
398
|
+
mockLastEstimateStorage,
|
|
399
|
+
);
|
|
351
400
|
|
|
352
401
|
const result = chooser.getGuess(
|
|
353
402
|
representations,
|
|
@@ -361,11 +410,14 @@ describe("GuessBasedChooser", () => {
|
|
|
361
410
|
});
|
|
362
411
|
|
|
363
412
|
it("should stop guess and downgrade when score is too low", () => {
|
|
364
|
-
mockScoreCalculator
|
|
413
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
365
414
|
createScoreData(0.9, ScoreConfidenceLevel.HIGH),
|
|
366
415
|
);
|
|
367
416
|
|
|
368
|
-
const chooser = new GuessBasedChooser(
|
|
417
|
+
const chooser = new GuessBasedChooser(
|
|
418
|
+
mockScoreCalculator,
|
|
419
|
+
mockLastEstimateStorage,
|
|
420
|
+
);
|
|
369
421
|
|
|
370
422
|
const result = chooser.getGuess(
|
|
371
423
|
representations,
|
|
@@ -379,11 +431,14 @@ describe("GuessBasedChooser", () => {
|
|
|
379
431
|
});
|
|
380
432
|
|
|
381
433
|
it("should stop guess when buffer gap is low and score is marginal", () => {
|
|
382
|
-
mockScoreCalculator
|
|
434
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
383
435
|
createScoreData(1.1, ScoreConfidenceLevel.HIGH),
|
|
384
436
|
);
|
|
385
437
|
|
|
386
|
-
const chooser = new GuessBasedChooser(
|
|
438
|
+
const chooser = new GuessBasedChooser(
|
|
439
|
+
mockScoreCalculator,
|
|
440
|
+
mockLastEstimateStorage,
|
|
441
|
+
);
|
|
387
442
|
|
|
388
443
|
const result = chooser.getGuess(
|
|
389
444
|
representations,
|
|
@@ -397,9 +452,12 @@ describe("GuessBasedChooser", () => {
|
|
|
397
452
|
});
|
|
398
453
|
|
|
399
454
|
it("should stop guess when score is undefined and buffer gap is low", () => {
|
|
400
|
-
mockScoreCalculator
|
|
455
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(undefined);
|
|
401
456
|
|
|
402
|
-
const chooser = new GuessBasedChooser(
|
|
457
|
+
const chooser = new GuessBasedChooser(
|
|
458
|
+
mockScoreCalculator,
|
|
459
|
+
mockLastEstimateStorage,
|
|
460
|
+
);
|
|
403
461
|
|
|
404
462
|
const result = chooser.getGuess(
|
|
405
463
|
representations,
|
|
@@ -413,11 +471,14 @@ describe("GuessBasedChooser", () => {
|
|
|
413
471
|
});
|
|
414
472
|
|
|
415
473
|
it("should block guesses for increasing duration after consecutive wrong guesses", () => {
|
|
416
|
-
mockScoreCalculator
|
|
474
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
417
475
|
createScoreData(0.9, ScoreConfidenceLevel.HIGH),
|
|
418
476
|
);
|
|
419
477
|
|
|
420
|
-
const chooser = new GuessBasedChooser(
|
|
478
|
+
const chooser = new GuessBasedChooser(
|
|
479
|
+
mockScoreCalculator,
|
|
480
|
+
mockLastEstimateStorage,
|
|
481
|
+
);
|
|
421
482
|
|
|
422
483
|
// First wrong guess
|
|
423
484
|
chooser.getGuess(
|
|
@@ -430,7 +491,7 @@ describe("GuessBasedChooser", () => {
|
|
|
430
491
|
|
|
431
492
|
// Try to guess again immediately
|
|
432
493
|
mocks.getMonotonicTimeStamp.mockReturnValue(10000 + 5000); // 5 seconds later
|
|
433
|
-
|
|
494
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
434
495
|
|
|
435
496
|
const result = chooser.getGuess(
|
|
436
497
|
representations,
|
|
@@ -445,11 +506,14 @@ describe("GuessBasedChooser", () => {
|
|
|
445
506
|
});
|
|
446
507
|
|
|
447
508
|
it("should allow guessing after block period expires", () => {
|
|
448
|
-
mockScoreCalculator
|
|
509
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
449
510
|
createScoreData(0.9, ScoreConfidenceLevel.HIGH),
|
|
450
511
|
);
|
|
451
512
|
|
|
452
|
-
const chooser = new GuessBasedChooser(
|
|
513
|
+
const chooser = new GuessBasedChooser(
|
|
514
|
+
mockScoreCalculator,
|
|
515
|
+
mockLastEstimateStorage,
|
|
516
|
+
);
|
|
453
517
|
|
|
454
518
|
// First wrong guess
|
|
455
519
|
chooser.getGuess(
|
|
@@ -462,8 +526,8 @@ describe("GuessBasedChooser", () => {
|
|
|
462
526
|
|
|
463
527
|
// Wait for block to expire
|
|
464
528
|
mocks.getMonotonicTimeStamp.mockReturnValue(10000 + 20000); // 20 seconds later
|
|
465
|
-
|
|
466
|
-
mockScoreCalculator
|
|
529
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
530
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
467
531
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
468
532
|
);
|
|
469
533
|
|
|
@@ -480,11 +544,14 @@ describe("GuessBasedChooser", () => {
|
|
|
480
544
|
});
|
|
481
545
|
|
|
482
546
|
it("should guess higher when conditions allow in guessing mode", () => {
|
|
483
|
-
mockScoreCalculator
|
|
547
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
484
548
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
485
549
|
);
|
|
486
550
|
|
|
487
|
-
const chooser = new GuessBasedChooser(
|
|
551
|
+
const chooser = new GuessBasedChooser(
|
|
552
|
+
mockScoreCalculator,
|
|
553
|
+
mockLastEstimateStorage,
|
|
554
|
+
);
|
|
488
555
|
|
|
489
556
|
const result = chooser.getGuess(
|
|
490
557
|
representations,
|
|
@@ -498,9 +565,12 @@ describe("GuessBasedChooser", () => {
|
|
|
498
565
|
});
|
|
499
566
|
|
|
500
567
|
it("should return current representation when score data is undefined and not stopping", () => {
|
|
501
|
-
mockScoreCalculator
|
|
568
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(undefined);
|
|
502
569
|
|
|
503
|
-
const chooser = new GuessBasedChooser(
|
|
570
|
+
const chooser = new GuessBasedChooser(
|
|
571
|
+
mockScoreCalculator,
|
|
572
|
+
mockLastEstimateStorage,
|
|
573
|
+
);
|
|
504
574
|
|
|
505
575
|
const result = chooser.getGuess(
|
|
506
576
|
representations,
|
|
@@ -516,9 +586,9 @@ describe("GuessBasedChooser", () => {
|
|
|
516
586
|
|
|
517
587
|
describe("request-based guess stopping", () => {
|
|
518
588
|
beforeEach(() => {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
mockScoreCalculator
|
|
589
|
+
mockLastEstimateStorage.representation = representations[2];
|
|
590
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
591
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
522
592
|
createScoreData(1.2, ScoreConfidenceLevel.HIGH),
|
|
523
593
|
);
|
|
524
594
|
});
|
|
@@ -528,7 +598,10 @@ describe("GuessBasedChooser", () => {
|
|
|
528
598
|
createRequest("rep-3", 0, 8000, true), // 2000ms elapsed (10000 - 8000)
|
|
529
599
|
];
|
|
530
600
|
|
|
531
|
-
const chooser = new GuessBasedChooser(
|
|
601
|
+
const chooser = new GuessBasedChooser(
|
|
602
|
+
mockScoreCalculator,
|
|
603
|
+
mockLastEstimateStorage,
|
|
604
|
+
);
|
|
532
605
|
|
|
533
606
|
const result = chooser.getGuess(
|
|
534
607
|
representations,
|
|
@@ -546,7 +619,10 @@ describe("GuessBasedChooser", () => {
|
|
|
546
619
|
createRequest("rep-3", 0, 9500, true), // 500ms elapsed
|
|
547
620
|
];
|
|
548
621
|
|
|
549
|
-
const chooser = new GuessBasedChooser(
|
|
622
|
+
const chooser = new GuessBasedChooser(
|
|
623
|
+
mockScoreCalculator,
|
|
624
|
+
mockLastEstimateStorage,
|
|
625
|
+
);
|
|
550
626
|
|
|
551
627
|
const result = chooser.getGuess(
|
|
552
628
|
representations,
|
|
@@ -564,7 +640,10 @@ describe("GuessBasedChooser", () => {
|
|
|
564
640
|
createRequest("rep-3", 2, 5000, false), // 5000ms elapsed, duration is 2s
|
|
565
641
|
];
|
|
566
642
|
|
|
567
|
-
const chooser = new GuessBasedChooser(
|
|
643
|
+
const chooser = new GuessBasedChooser(
|
|
644
|
+
mockScoreCalculator,
|
|
645
|
+
mockLastEstimateStorage,
|
|
646
|
+
);
|
|
568
647
|
|
|
569
648
|
const result = chooser.getGuess(
|
|
570
649
|
representations,
|
|
@@ -582,7 +661,10 @@ describe("GuessBasedChooser", () => {
|
|
|
582
661
|
createRequest("rep-3", 2, 8500, false), // 1500ms elapsed, duration is 2s (threshold: 2200ms)
|
|
583
662
|
];
|
|
584
663
|
|
|
585
|
-
const chooser = new GuessBasedChooser(
|
|
664
|
+
const chooser = new GuessBasedChooser(
|
|
665
|
+
mockScoreCalculator,
|
|
666
|
+
mockLastEstimateStorage,
|
|
667
|
+
);
|
|
586
668
|
|
|
587
669
|
const result = chooser.getGuess(
|
|
588
670
|
representations,
|
|
@@ -600,7 +682,10 @@ describe("GuessBasedChooser", () => {
|
|
|
600
682
|
|
|
601
683
|
const requests = [createRequest("rep-3", 2, 9000, false)];
|
|
602
684
|
|
|
603
|
-
const chooser = new GuessBasedChooser(
|
|
685
|
+
const chooser = new GuessBasedChooser(
|
|
686
|
+
mockScoreCalculator,
|
|
687
|
+
mockLastEstimateStorage,
|
|
688
|
+
);
|
|
604
689
|
|
|
605
690
|
const result = chooser.getGuess(
|
|
606
691
|
representations,
|
|
@@ -616,11 +701,14 @@ describe("GuessBasedChooser", () => {
|
|
|
616
701
|
it("should not consider requests for other representations", () => {
|
|
617
702
|
const requests = [createRequest("rep-4", 2, 5000, false)];
|
|
618
703
|
|
|
619
|
-
mockScoreCalculator
|
|
704
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
620
705
|
createScoreData(1.1, ScoreConfidenceLevel.HIGH),
|
|
621
706
|
);
|
|
622
707
|
|
|
623
|
-
const chooser = new GuessBasedChooser(
|
|
708
|
+
const chooser = new GuessBasedChooser(
|
|
709
|
+
mockScoreCalculator,
|
|
710
|
+
mockLastEstimateStorage,
|
|
711
|
+
);
|
|
624
712
|
|
|
625
713
|
const result = chooser.getGuess(
|
|
626
714
|
representations,
|
|
@@ -640,7 +728,10 @@ describe("GuessBasedChooser", () => {
|
|
|
640
728
|
createRequest("rep-3", 2, 9000, false), // OK
|
|
641
729
|
];
|
|
642
730
|
|
|
643
|
-
const chooser = new GuessBasedChooser(
|
|
731
|
+
const chooser = new GuessBasedChooser(
|
|
732
|
+
mockScoreCalculator,
|
|
733
|
+
mockLastEstimateStorage,
|
|
734
|
+
);
|
|
644
735
|
|
|
645
736
|
const result = chooser.getGuess(
|
|
646
737
|
representations,
|
|
@@ -656,16 +747,19 @@ describe("GuessBasedChooser", () => {
|
|
|
656
747
|
|
|
657
748
|
describe("guess validation", () => {
|
|
658
749
|
beforeEach(() => {
|
|
659
|
-
|
|
660
|
-
|
|
750
|
+
mockLastEstimateStorage.representation = representations[2];
|
|
751
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
661
752
|
});
|
|
662
753
|
|
|
663
754
|
it("should validate guess with high score and high confidence", () => {
|
|
664
|
-
mockScoreCalculator
|
|
755
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
665
756
|
createScoreData(1.6, ScoreConfidenceLevel.HIGH),
|
|
666
757
|
);
|
|
667
758
|
|
|
668
|
-
const chooser = new GuessBasedChooser(
|
|
759
|
+
const chooser = new GuessBasedChooser(
|
|
760
|
+
mockScoreCalculator,
|
|
761
|
+
mockLastEstimateStorage,
|
|
762
|
+
);
|
|
669
763
|
|
|
670
764
|
chooser.getGuess(
|
|
671
765
|
representations,
|
|
@@ -688,11 +782,14 @@ describe("GuessBasedChooser", () => {
|
|
|
688
782
|
});
|
|
689
783
|
|
|
690
784
|
it("should validate guess when incoming bitrate matches and it's an improvement", () => {
|
|
691
|
-
mockScoreCalculator
|
|
785
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
692
786
|
createScoreData(1.2, ScoreConfidenceLevel.LOW),
|
|
693
787
|
);
|
|
694
788
|
|
|
695
|
-
const chooser = new GuessBasedChooser(
|
|
789
|
+
const chooser = new GuessBasedChooser(
|
|
790
|
+
mockScoreCalculator,
|
|
791
|
+
mockLastEstimateStorage,
|
|
792
|
+
);
|
|
696
793
|
|
|
697
794
|
const result = chooser.getGuess(
|
|
698
795
|
representations,
|
|
@@ -709,13 +806,16 @@ describe("GuessBasedChooser", () => {
|
|
|
709
806
|
|
|
710
807
|
describe("edge cases", () => {
|
|
711
808
|
it("should handle infinite buffer gap correctly", () => {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
mockScoreCalculator
|
|
809
|
+
mockLastEstimateStorage.representation = representations[1];
|
|
810
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
811
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
715
812
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
716
813
|
);
|
|
717
814
|
|
|
718
|
-
const chooser = new GuessBasedChooser(
|
|
815
|
+
const chooser = new GuessBasedChooser(
|
|
816
|
+
mockScoreCalculator,
|
|
817
|
+
mockLastEstimateStorage,
|
|
818
|
+
);
|
|
719
819
|
|
|
720
820
|
const result = chooser.getGuess(
|
|
721
821
|
representations,
|
|
@@ -729,13 +829,16 @@ describe("GuessBasedChooser", () => {
|
|
|
729
829
|
});
|
|
730
830
|
|
|
731
831
|
it("should handle NaN buffer gap by not guessing", () => {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
mockScoreCalculator
|
|
832
|
+
mockLastEstimateStorage.representation = representations[1];
|
|
833
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
834
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
735
835
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
736
836
|
);
|
|
737
837
|
|
|
738
|
-
const chooser = new GuessBasedChooser(
|
|
838
|
+
const chooser = new GuessBasedChooser(
|
|
839
|
+
mockScoreCalculator,
|
|
840
|
+
mockLastEstimateStorage,
|
|
841
|
+
);
|
|
739
842
|
|
|
740
843
|
const result = chooser.getGuess(
|
|
741
844
|
representations,
|
|
@@ -749,13 +852,16 @@ describe("GuessBasedChooser", () => {
|
|
|
749
852
|
});
|
|
750
853
|
|
|
751
854
|
it("should cap block duration at 120 seconds", () => {
|
|
752
|
-
mockScoreCalculator
|
|
855
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
753
856
|
createScoreData(0.9, ScoreConfidenceLevel.HIGH),
|
|
754
857
|
);
|
|
755
|
-
|
|
756
|
-
|
|
858
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.GuessBased;
|
|
859
|
+
mockLastEstimateStorage.representation = representations[2];
|
|
757
860
|
|
|
758
|
-
const chooser = new GuessBasedChooser(
|
|
861
|
+
const chooser = new GuessBasedChooser(
|
|
862
|
+
mockScoreCalculator,
|
|
863
|
+
mockLastEstimateStorage,
|
|
864
|
+
);
|
|
759
865
|
|
|
760
866
|
// Trigger many consecutive wrong guesses
|
|
761
867
|
for (let i = 0; i < 20; i++) {
|
|
@@ -772,9 +878,9 @@ describe("GuessBasedChooser", () => {
|
|
|
772
878
|
// The block should be capped at 120 seconds max
|
|
773
879
|
// After 120 seconds, should be able to guess again
|
|
774
880
|
mocks.getMonotonicTimeStamp.mockReturnValue(10000 + 20000 + 120100);
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
mockScoreCalculator
|
|
881
|
+
mockLastEstimateStorage.algorithmType = ABRAlgorithmType.BufferBased;
|
|
882
|
+
mockLastEstimateStorage.representation = representations[1]; // Update to reflect actual downgraded state
|
|
883
|
+
vi.spyOn(mockScoreCalculator, "getEstimate").mockReturnValue(
|
|
778
884
|
createScoreData(1.5, ScoreConfidenceLevel.HIGH),
|
|
779
885
|
);
|
|
780
886
|
|