1 # Copyright 2015 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import logging 6 import os 7 8 from autotest_lib.client.bin import test 9 from autotest_lib.client.bin import utils 10 from autotest_lib.client.common_lib import error 11 from autotest_lib.client.common_lib.cros import chrome 12 from autotest_lib.client.cros.video import helper_logger 13 14 EXTRA_BROWSER_ARGS = ['--use-fake-ui-for-media-stream'] 15 16 # Polling timeout. 17 TIMEOUT = 90 18 19 20 class video_WebRtcPeerConnectionWithCamera(test.test): 21 """Tests a full WebRTC call with a real webcam.""" 22 version = 1 23 24 def start_loopback(self, cr, video_codec): 25 """Opens WebRTC loopback page. 26 27 @param cr: Autotest Chrome instance. 28 @param video_codec: video codec to use. 29 """ 30 cr.browser.platform.SetHTTPServerDirectories(self.bindir) 31 32 self.tab = cr.browser.tabs[0] 33 self.tab.Navigate(cr.browser.platform.http_server.UrlOf( 34 os.path.join(self.bindir, 'loopback.html'))) 35 self.tab.WaitForDocumentReadyStateToBeComplete() 36 self.tab.EvaluateJavaScript( 37 "testWebRtcLoopbackCall('%s')" % video_codec) 38 39 def wait_test_completed(self, timeout_secs): 40 """Waits until the test is done. 41 42 @param timeout_secs Max time to wait in seconds. 43 44 @raises TestError on timeout, or javascript eval fails. 45 """ 46 def _test_done(): 47 status = self.tab.EvaluateJavaScript('getStatus()') 48 logging.debug(status); 49 return status != 'running' 50 51 utils.poll_for_condition( 52 _test_done, timeout=timeout_secs, sleep_interval=1, 53 desc='loopback.html reports itself as finished') 54 55 @helper_logger.video_log_wrapper 56 def run_once(self, video_codec): 57 """Runs the video_WebRtcPeerConnectionWithCamera test. 58 59 @param video_codec: video codec to use. 60 """ 61 with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS +\ 62 [helper_logger.chrome_vmodule_flag()], 63 init_network_controller=True) as cr: 64 self.start_loopback(cr, video_codec) 65 self.wait_test_completed(TIMEOUT) 66 self.print_loopback_result(video_codec) 67 68 def print_loopback_result(self, video_codec): 69 """Prints loopback results (unless we failed to retrieve them). 70 71 @param video_codec: video codec to use. 72 @raises TestError if the test failed outright. 73 """ 74 status = self.tab.EvaluateJavaScript('getStatus()') 75 if status != 'ok-done': 76 raise error.TestFail('Failed: %s' % status) 77 78 results = self.tab.EvaluateJavaScript('getResults()') 79 logging.info('Camera Type: %s', results['cameraType']) 80 logging.info('PeerConnectionstats: %s', results['peerConnectionStats']) 81 logging.info('FrameStats: %s', results['frameStats']) 82 83 pc_stats = results.get('peerConnectionStats') 84 if not pc_stats: 85 raise error.TestFail('Peer Connection Stats is empty') 86 self.output_perf_value( 87 description='max_input_fps_%s' % video_codec, 88 value=pc_stats[1], units='fps', higher_is_better=True) 89 self.output_perf_value( 90 description='max_sent_fps_%s' % video_codec, 91 value=pc_stats[4], units='fps', higher_is_better=True) 92 93 frame_stats = results.get('frameStats') 94 if not frame_stats: 95 raise error.TestFail('Frame Stats is empty') 96 97 self.output_perf_value( 98 description='black_frames_%s' % video_codec, 99 value=frame_stats['numBlackFrames'], 100 units='frames', higher_is_better=False) 101 self.output_perf_value( 102 description='frozen_frames_%s' % video_codec, 103 value=frame_stats['numFrozenFrames'], 104 units='frames', higher_is_better=False) 105 self.output_perf_value( 106 description='total_num_frames_%s' % video_codec, 107 value=frame_stats['numFrames'], 108 units='frames', higher_is_better=True) 109