Home | History | Annotate | Download | only in video_WebRtcResolutionSwitching
      1 /*
      2  * Copyright 2017 The Chromium Authors. All rights reserved.
      3  * Use of this source code is governed by a BSD-style license that can be
      4  * found in the LICENSE file.
      5  */
      6 /*jshint esversion: 6 */
      7 
      8 'use strict';
      9 
     10 const $ = document.getElementById.bind(document);
     11 
     12 function logError(err) {
     13   console.error(err);
     14 }
     15 
     16 // Available resolutions to switch between. These are 4:3 resolutions chosen
     17 // since they have significant distance between them and are quite common. E.g.
     18 // they can be selected for youtube videos. We also avoid higher resolutions
     19 // since they consume a lot of resources.
     20 const RESOLUTIONS = [
     21   {w:320, h:240},
     22   {w:480, h:360},
     23   {w:640, h:480},
     24   {w:1280, h:720},
     25 ];
     26 
     27 class TestRunner {
     28   constructor(runtimeSeconds, switchResolutionDelayMillis) {
     29     this.runtimeSeconds = runtimeSeconds;
     30     this.switchResolutionDelayMillis = switchResolutionDelayMillis;
     31     this.videoElements = [];
     32     this.peerConnections = [];
     33     this.numConnections = 0;
     34     this.iteration = 0;
     35     this.startTime = 0;  // initialized to dummy value
     36     this.status = this.getStatusInternal_();
     37   }
     38 
     39   addPeerConnection() {
     40     const videoElement = document.createElement('video');
     41     videoElement.autoplay = true;
     42     $('body').appendChild(videoElement);
     43     this.videoElements.push(videoElement);
     44     this.peerConnections.push(
     45         new PeerConnection(videoElement, RESOLUTIONS, cpuOveruseDetection));
     46   }
     47 
     48   runTest() {
     49     const promises = this.peerConnections.map((conn) => conn.start());
     50     Promise.all(promises)
     51         .then(() => {
     52           this.startTime = Date.now();
     53           this.switchResolutionLoop();
     54         })
     55         .catch((e) => {throw e});
     56   }
     57 
     58   switchResolutionLoop() {
     59     this.iteration++;
     60     this.status = this.getStatusInternal_();
     61     $('status').textContent = this.status;
     62     if (this.status != 'ok-done') {
     63       Promise.all(this.peerConnections.map((pc) => pc.switchToRandomStream()))
     64           .then(
     65               () => setTimeout(
     66                   () => this.switchResolutionLoop(),
     67                   this.switchResolutionDelayMillis));
     68     }
     69   }
     70 
     71   getStatus() {
     72     return this.status;
     73   }
     74 
     75   getStatusInternal_() {
     76     if (this.iteration == 0) {
     77       return 'not-started';
     78     }
     79     try {
     80       this.peerConnections.forEach((conn) => conn.verifyState());
     81     } catch (e) {
     82       return `failure: ${e.message}`;
     83     }
     84     const timeSpent = Date.now() - this.startTime;
     85     if (timeSpent >= this.runtimeSeconds * 1000) {
     86       return 'ok-done';
     87     }
     88     return `running, iteration: ${this.iteration}`;
     89   }
     90 }
     91 
     92 // Declare testRunner so that the Python code can access it to query status.
     93 // Also allows us to access it easily in dev tools for debugging.
     94 let testRunner;
     95 // Set from the Python test runner
     96 let cpuOveruseDetection = null;
     97 
     98 function startTest(
     99     runtimeSeconds, numPeerConnections, switchResolutionDelayMillis) {
    100   testRunner = new TestRunner(runtimeSeconds, switchResolutionDelayMillis);
    101   for (let i = 0; i < numPeerConnections; i++) {
    102     testRunner.addPeerConnection();
    103   }
    104   testRunner.runTest();
    105 }
    106 
    107 function getStatus() {
    108   return testRunner ? testRunner.getStatus() : 'not-initialized';
    109 }
    110 
    111