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