<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.controller {
    import org.mangui.hls.constant.HLSLoaderTypes;
    import org.mangui.hls.constant.HLSMaxLevelCappingMode;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.event.HLSLoadMetrics;
    import org.mangui.hls.HLS;
    import org.mangui.hls.HLSSettings;
    import org.mangui.hls.model.Level;

    CONFIG::LOGGING {
        import org.mangui.hls.utils.Log;
    }
    /** Class that manages auto level selection
     *
     * this is an implementation based on Serial segment fetching method from
     * http://www.cs.tut.fi/~moncef/publications/rate-adaptation-IC-2011.pdf
     */
    public class LevelController {
        /** Reference to the HLS controller. **/
        private var _hls : HLS;
        /** switch up threshold **/
        private var _switchup : Vector.<Number> = null;
        /** switch down threshold **/
        private var _switchdown : Vector.<Number> = null;
        /** bitrate array **/
        private var _bitrate : Vector.<uint> = null;
        /** vector of levels with unique dimension with highest bandwidth **/
        private var _maxUniqueLevels : Vector.<Level> = null;
        /** nb level **/
        private var _nbLevel : int = 0;
        private var _lastSegmentDuration : Number;
        private var _lastFetchDuration : Number;
        private var  lastBandwidth : int;
        private var  _autoLevelCapping : int;
        private var  _startLevel : int = -1;
        private var  _fpsController : FPSController;

        /** Create the loader. **/
        public function LevelController(hls : HLS) : void {
            _hls = hls;
            _fpsController = new FPSController(hls);
            /* low priority listener, so that other listeners with default priority
               could seamlessly set hls.startLevel in their HLSEvent.MANIFEST_PARSED listener */
            _hls.addEventListener(HLSEvent.MANIFEST_PARSED, _manifestParsedHandler, false, int.MIN_VALUE);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED, _fragmentLoadedHandler);
        }
        ;

        public function dispose() : void {
            _fpsController.dispose();
            _fpsController = null;
            _hls.removeEventListener(HLSEvent.MANIFEST_PARSED, _manifestParsedHandler);
            _hls.removeEventListener(HLSEvent.MANIFEST_LOADED, _manifestLoadedHandler);
            _hls.removeEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.removeEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED, _fragmentLoadedHandler);
        }

        private function _fragmentLoadedHandler(event : HLSEvent) : void {
            var metrics : HLSLoadMetrics = event.loadMetrics;
            // only monitor main fragment metrics for level switching
            if(metrics.type == HLSLoaderTypes.FRAGMENT_MAIN) {
                lastBandwidth = metrics.bandwidth;
                _lastSegmentDuration = metrics.duration;
                _lastFetchDuration = metrics.processing_duration;
            }
        }

        private function _manifestParsedHandler(event : HLSEvent) : void {
            if(HLSSettings.autoStartLoad) {
                // upon manifest parsed event, trigger a level switch to load startLevel playlist
                _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, _hls.startLevel));
            }
        }

        private function _manifestLoadedHandler(event : HLSEvent) : void {
            var levels : Vector.<Level> = event.levels;
            var maxswitchup : Number = 0;
            var minswitchdwown : Number = Number.MAX_VALUE;
            _nbLevel = levels.length;
            _bitrate = new Vector.<uint>(_nbLevel, true);
            _switchup = new Vector.<Number>(_nbLevel, true);
            _switchdown = new Vector.<Number>(_nbLevel, true);
            _autoLevelCapping = -1;
            _lastSegmentDuration = 0;
            _lastFetchDuration = 0;
            lastBandwidth = 0;

            var i : int;

            for (i = 0; i < _nbLevel; i++) {
                _bitrate[i] = levels[i].bitrate;
            }

            for (i = 0; i < _nbLevel - 1; i++) {
                _switchup[i] = (_bitrate[i + 1] - _bitrate[i]) / _bitrate[i];
                maxswitchup = Math.max(maxswitchup, _switchup[i]);
            }
            for (i = 0; i < _nbLevel - 1; i++) {
                _switchup[i] = Math.min(maxswitchup, 2 * _switchup[i]);
<commit_msg>LevelController: use startLevel getter directly<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.controller {
    import org.mangui.hls.constant.HLSLoaderTypes;
    import org.mangui.hls.constant.HLSMaxLevelCappingMode;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.event.HLSLoadMetrics;
    import org.mangui.hls.HLS;
    import org.mangui.hls.HLSSettings;
    import org.mangui.hls.model.Level;

    CONFIG::LOGGING {
        import org.mangui.hls.utils.Log;
    }
    /** Class that manages auto level selection
     *
     * this is an implementation based on Serial segment fetching method from
     * http://www.cs.tut.fi/~moncef/publications/rate-adaptation-IC-2011.pdf
     */
    public class LevelController {
        /** Reference to the HLS controller. **/
        private var _hls : HLS;
        /** switch up threshold **/
        private var _switchup : Vector.<Number> = null;
        /** switch down threshold **/
        private var _switchdown : Vector.<Number> = null;
        /** bitrate array **/
        private var _bitrate : Vector.<uint> = null;
        /** vector of levels with unique dimension with highest bandwidth **/
        private var _maxUniqueLevels : Vector.<Level> = null;
        /** nb level **/
        private var _nbLevel : int = 0;
        private var _lastSegmentDuration : Number;
        private var _lastFetchDuration : Number;
        private var  lastBandwidth : int;
        private var  _autoLevelCapping : int;
        private var  _startLevel : int = -1;
        private var  _fpsController : FPSController;

        /** Create the loader. **/
        public function LevelController(hls : HLS) : void {
            _hls = hls;
            _fpsController = new FPSController(hls);
            /* low priority listener, so that other listeners with default priority
               could seamlessly set hls.startLevel in their HLSEvent.MANIFEST_PARSED listener */
            _hls.addEventListener(HLSEvent.MANIFEST_PARSED, _manifestParsedHandler, false, int.MIN_VALUE);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED, _fragmentLoadedHandler);
        }
        ;

        public function dispose() : void {
            _fpsController.dispose();
            _fpsController = null;
            _hls.removeEventListener(HLSEvent.MANIFEST_PARSED, _manifestParsedHandler);
            _hls.removeEventListener(HLSEvent.MANIFEST_LOADED, _manifestLoadedHandler);
            _hls.removeEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.removeEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED, _fragmentLoadedHandler);
        }

        private function _fragmentLoadedHandler(event : HLSEvent) : void {
            var metrics : HLSLoadMetrics = event.loadMetrics;
            // only monitor main fragment metrics for level switching
            if(metrics.type == HLSLoaderTypes.FRAGMENT_MAIN) {
                lastBandwidth = metrics.bandwidth;
                _lastSegmentDuration = metrics.duration;
                _lastFetchDuration = metrics.processing_duration;
            }
        }

        private function _manifestParsedHandler(event : HLSEvent) : void {
            if(HLSSettings.autoStartLoad) {
                // upon manifest parsed event, trigger a level switch to load startLevel playlist
                _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, startLevel));
            }
        }

        private function _manifestLoadedHandler(event : HLSEvent) : void {
            var levels : Vector.<Level> = event.levels;
            var maxswitchup : Number = 0;
            var minswitchdwown : Number = Number.MAX_VALUE;
            _nbLevel = levels.length;
            _bitrate = new Vector.<uint>(_nbLevel, true);
            _switchup = new Vector.<Number>(_nbLevel, true);
            _switchdown = new Vector.<Number>(_nbLevel, true);
            _autoLevelCapping = -1;
            _lastSegmentDuration = 0;
            _lastFetchDuration = 0;
            lastBandwidth = 0;

            var i : int;

            for (i = 0; i < _nbLevel; i++) {
                _bitrate[i] = levels[i].bitrate;
            }

            for (i = 0; i < _nbLevel - 1; i++) {
                _switchup[i] = (_bitrate[i + 1] - _bitrate[i]) / _bitrate[i];
                maxswitchup = Math.max(maxswitchup, _switchup[i]);
            }
            for (i = 0; i < _nbLevel - 1; i++) {
                _switchup[i] = Math.min(maxswitchup, 2 * _switchup[i]);

{'fraction_non_alphanumeric': 0.09084369540643304, 'fraction_numerical': 0.004521631898057754, 'mean_word_length': 2.2635814889336014, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6264487', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2764, 'n_words': 666}