Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Side by Side Diff: content/test/data/media/webrtc_test_audio.js

Issue 1132483003: Rewriting WebRTC output level tests to be more reliable under load. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Audio test utilities. 5 // Audio test utilities.
6 6
7 // GetStats reports audio output energy in the [0, 32768] range. 7 // GetStats reports audio output energy in the [0, 32768] range.
8 var MAX_AUDIO_OUTPUT_ENERGY = 32768; 8 var MAX_AUDIO_OUTPUT_ENERGY = 32768;
9 9
10 // Queries WebRTC stats on |peerConnection| to find out whether audio is playing 10 // Queries WebRTC stats on |peerConnection| to find out whether audio is playing
11 // on the connection. Note this does not necessarily mean the audio is actually 11 // on the connection. Note this does not necessarily mean the audio is actually
12 // playing out (for instance if there's a bug in the WebRTC web media player). 12 // playing out (for instance if there's a bug in the WebRTC web media player).
13 // If |beLenient| is true, we assume we're on a slow and unreliable bot and that 13 // If |beLenient| is true, we assume we're on a slow and unreliable bot and that
14 // we should do a minimum of checking. 14 // we should do a minimum of checking.
15 function ensureAudioPlaying(peerConnection, beLenient) { 15 function ensureAudioPlaying(peerConnection, beLenient) {
16 addExpectedEvent(); 16 addExpectedEvent();
17 17
18 // Gather 50 samples per second for 2 seconds. 18 gatherAudioLevelSamples(peerConnection, 3 * 1000, function(samples) {
19 gatherAudioLevelSamples(peerConnection, 100, 50, function(samples) {
20 identifyFakeDeviceSignal_(samples, beLenient); 19 identifyFakeDeviceSignal_(samples, beLenient);
21 eventOccured(); 20 eventOccured();
22 }); 21 });
23 } 22 }
24 23
25 // Queries WebRTC stats on |peerConnection| to find out whether audio is muted 24 // Queries WebRTC stats on |peerConnection| to find out whether audio is muted
26 // on the connection. 25 // on the connection.
27 function ensureSilence(peerConnection) { 26 function ensureSilence(peerConnection) {
28 addExpectedEvent(); 27 addExpectedEvent();
29 setTimeout(function() { 28 setTimeout(function() {
30 gatherAudioLevelSamples(peerConnection, 100, 50, function(samples) { 29 gatherAudioLevelSamples(peerConnection, 1 * 1000, function(samples) {
31 identifySilence_(samples); 30 identifySilence_(samples);
32 eventOccured(); 31 eventOccured();
33 }); 32 });
34 }, 500); 33 }, 500);
35 } 34 }
36 35
37 // Not sure if this is a bug, but sometimes we get several audio ssrc's where 36 // Not sure if this is a bug, but sometimes we get several audio ssrc's where
38 // just reports audio level zero. Think of the nonzero level as the more 37 // just reports audio level zero. Think of the nonzero level as the more
39 // credible one here. http://crbug.com/479147. 38 // credible one here. http://crbug.com/479147.
40 function workAroundSeveralReportsIssue(audioOutputLevels) { 39 function workAroundSeveralReportsIssue(audioOutputLevels) {
41 if (audioOutputLevels.length == 1) { 40 if (audioOutputLevels.length == 1) {
42 return audioOutputLevels[0]; 41 return audioOutputLevels[0];
43 } 42 }
44 43
45 console.log("Hit issue where one report batch returns two or more reports " + 44 console.log("Hit issue where one report batch returns two or more reports " +
46 "with audioReportLevel; got " + audioOutputLevels); 45 "with audioReportLevel; got " + audioOutputLevels);
47 46
48 return Math.max(audioOutputLevels[0], audioOutputLevels[1]); 47 return Math.max(audioOutputLevels[0], audioOutputLevels[1]);
49 } 48 }
50 49
51 // Gathers |numSamples| samples at |frequency| number of times per second and 50 // Gathers samples from WebRTC stats as fast as possible for |durationMs|
52 // calls back |callback| with an array with numbers in the [0, 32768] range. 51 // milliseconds and calls back |callback| with an array with numbers in the
53 function gatherAudioLevelSamples(peerConnection, numSamples, frequency, 52 // [0, 32768] range. There are no guarantees for how often we will be able to
54 callback) { 53 // collect values, but this function deliberately avoids setTimeout calls in
55 console.log('Gathering ' + numSamples + ' audio samples...'); 54 // order be as insensitive as possible to starvation (particularly when this
55 // code runs in parallel with other tests on a heavily loaded bot).
56 function gatherAudioLevelSamples(peerConnection, durationMs, callback) {
57 console.log('Gathering audio samples for ' + durationMs + ' milliseconds...');
56 var audioLevelSamples = [] 58 var audioLevelSamples = []
57 59
58 // If this times out and never found any audio output levels, the call 60 // If this times out and never found any audio output levels, the call
59 // probably doesn't have an audio stream. 61 // probably doesn't have an audio stream.
60 var gatherSamples = setInterval(function() { 62 var startTime = new Date();
61 peerConnection.getStats(function(response) { 63 var gotStats = function(response) {
62 audioOutputLevels = getAudioLevelFromStats_(response); 64 audioOutputLevels = getAudioLevelFromStats_(response);
63 if (audioOutputLevels.length == 0) { 65 if (audioOutputLevels.length == 0) {
64 // The call probably isn't up yet. 66 // The call probably isn't up yet.
65 return; 67 peerConnection.getStats(gotStats);
66 } 68 return;
67 var outputLevel = workAroundSeveralReportsIssue(audioOutputLevels); 69 }
68 audioLevelSamples.push(outputLevel); 70 var outputLevel = workAroundSeveralReportsIssue(audioOutputLevels);
71 audioLevelSamples.push(outputLevel);
69 72
70 if (audioLevelSamples.length == numSamples) { 73 var elapsed = new Date() - startTime;
71 console.log('Gathered all samples.'); 74 if (elapsed > durationMs) {
72 clearInterval(gatherSamples); 75 console.log('Gathered all samples.');
73 callback(audioLevelSamples); 76 callback(audioLevelSamples);
74 } 77 return;
75 }); 78 }
76 }, 1000 / frequency); 79 peerConnection.getStats(gotStats);
80 }
81 peerConnection.getStats(gotStats);
77 } 82 }
78 83
79 /** 84 /**
80 * Tries to identify the beep-every-half-second signal generated by the fake 85 * Tries to identify the beep-every-half-second signal generated by the fake
81 * audio device in media/video/capture/fake_video_capture_device.cc. Fails the 86 * audio device in media/video/capture/fake_video_capture_device.cc. Fails the
82 * test if we can't see a signal. The samples should have been gathered over at 87 * test if we can't see a signal. The samples should have been gathered over at
83 * least two seconds since we expect to see at least three "peaks" in there 88 * least two seconds since we expect to see at least three "peaks" in there
84 * (we should see either 3 or 4 depending on how things line up). 89 * (we should see either 3 or 4 depending on how things line up).
85 * 90 *
86 * If |beLenient| is specified, we assume we're running on a slow device or 91 * If |beLenient| is specified, we assume we're running on a slow device or
87 * or under TSAN, and relax the checks quite a bit. 92 * or under TSAN, and relax the checks quite a bit.
88 * 93 *
89 * @private 94 * @private
90 */ 95 */
91 function identifyFakeDeviceSignal_(samples, beLenient) { 96 function identifyFakeDeviceSignal_(samples, beLenient) {
92 var numPeaks = 0; 97 var numPeaks = 0;
93 var threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.7; 98 var threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.7;
94 if (beLenient) 99 if (beLenient)
95 threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.6; 100 threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.6;
96 var currentlyOverThreshold = false; 101 var currentlyOverThreshold = false;
97 102
98 // Detect when we have been been over the threshold and is going back again 103 // Detect when we have been been over the threshold and is going back again
99 // (i.e. count peaks). We should see about one peak per second. 104 // (i.e. count peaks). We should see about two peaks per second.
100 for (var i = 0; i < samples.length; ++i) { 105 for (var i = 0; i < samples.length; ++i) {
101 if (currentlyOverThreshold && samples[i] < threshold) 106 if (currentlyOverThreshold && samples[i] < threshold)
102 numPeaks++; 107 numPeaks++;
103 currentlyOverThreshold = samples[i] >= threshold; 108 currentlyOverThreshold = samples[i] >= threshold;
104 } 109 }
105 110
106 console.log('Number of peaks identified: ' + numPeaks); 111 console.log('Number of peaks identified: ' + numPeaks);
107 112
108 var expectedPeaks = 2; 113 var expectedPeaks = 2;
109 if (beLenient) 114 if (beLenient)
(...skipping 26 matching lines...) Expand all
136 var reports = response.result(); 141 var reports = response.result();
137 var audioOutputLevels = []; 142 var audioOutputLevels = [];
138 for (var i = 0; i < reports.length; ++i) { 143 for (var i = 0; i < reports.length; ++i) {
139 var report = reports[i]; 144 var report = reports[i];
140 if (report.names().indexOf('audioOutputLevel') != -1) { 145 if (report.names().indexOf('audioOutputLevel') != -1) {
141 audioOutputLevels.push(report.stat('audioOutputLevel')); 146 audioOutputLevels.push(report.stat('audioOutputLevel'));
142 } 147 }
143 } 148 }
144 return audioOutputLevels; 149 return audioOutputLevels;
145 } 150 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698