Home | History | Annotate | Download | only in video_WebRtcPeerConnectionWithCamera
      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 import time
      8 
      9 from autotest_lib.client.bin import test
     10 from autotest_lib.client.bin import utils
     11 from autotest_lib.client.common_lib import error
     12 from autotest_lib.client.common_lib.cros import chrome
     13 from autotest_lib.client.cros.video import device_capability
     14 from autotest_lib.client.cros.video import helper_logger
     15 
     16 EXTRA_BROWSER_ARGS = ['--use-fake-ui-for-media-stream']
     17 
     18 # Variables from the getusermedia.html page.
     19 IS_VIDEO_INPUT_FOUND = 'isVideoInputFound'
     20 
     21 # Polling timeout.
     22 TIMEOUT = 90
     23 
     24 
     25 class video_WebRtcPeerConnectionWithCamera(test.test):
     26     """Tests a full WebRTC call with a real webcam."""
     27     version = 1
     28 
     29     def cleanup(self):
     30         """Autotest cleanup function
     31 
     32         It is run by common_lib/test.py.
     33         """
     34         if utils.is_virtual_machine():
     35             try:
     36                 utils.run('sudo modprobe -r vivid')
     37             except Exception as e:
     38                 raise error.TestFail('Failed to unload vivid', e)
     39 
     40     def start_loopback(self, cr, video_codec):
     41         """Opens WebRTC loopback page.
     42 
     43         @param cr: Autotest Chrome instance.
     44         @param video_codec: video codec to use.
     45         """
     46         cr.browser.platform.SetHTTPServerDirectories(self.bindir)
     47 
     48         self.tab = cr.browser.tabs[0]
     49         self.tab.Navigate(cr.browser.platform.http_server.UrlOf(
     50                 os.path.join(self.bindir, 'loopback.html')))
     51         self.tab.WaitForDocumentReadyStateToBeComplete()
     52 
     53         if utils.is_virtual_machine():
     54             # Make sure if Chrome has already recognized vivid as an
     55             # external camera before calling 'getUserMedia()'.
     56             self.wait_camera_detected()
     57 
     58         self.tab.EvaluateJavaScript(
     59                 "testWebRtcLoopbackCall('%s')" % video_codec)
     60 
     61     def wait_camera_detected(self):
     62         """Waits until a camera is detected.
     63         """
     64         for _ in range(10):
     65             self.tab.EvaluateJavaScript('checkVideoInput()')
     66             if self.tab.EvaluateJavaScript(IS_VIDEO_INPUT_FOUND):
     67                 return
     68             time.sleep(1)
     69 
     70         raise error.TestFail('Can not find video input device')
     71 
     72     def wait_test_completed(self, timeout_secs):
     73         """Waits until the test is done.
     74 
     75         @param timeout_secs Max time to wait in seconds.
     76 
     77         @raises TestError on timeout, or javascript eval fails.
     78         """
     79         def _test_done():
     80             status = self.tab.EvaluateJavaScript('getStatus()')
     81             logging.debug(status);
     82             return status != 'running'
     83 
     84         utils.poll_for_condition(
     85             _test_done, timeout=timeout_secs, sleep_interval=1,
     86             desc='loopback.html reports itself as finished')
     87 
     88     @helper_logger.video_log_wrapper
     89     def run_once(self, video_codec, capability):
     90         """Runs the video_WebRtcPeerConnectionWithCamera test.
     91 
     92         @param video_codec: video codec to use.
     93         @param capability: Capability required for executing this test.
     94         """
     95         device_capability.DeviceCapability().ensure_capability(capability)
     96         with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS +\
     97                            [helper_logger.chrome_vmodule_flag()],
     98                            init_network_controller=True) as cr:
     99 
    100             # TODO(keiichiw): vivid should be loaded in self.setup() after
    101             # crbug.com/871185 is fixed
    102             if utils.is_virtual_machine():
    103                 try:
    104                     utils.run('sudo modprobe vivid n_devs=1 node_types=0x1')
    105                 except Exception as e:
    106                     raise error.TestFail('Failed to load vivid', e)
    107 
    108             self.start_loopback(cr, video_codec)
    109             self.wait_test_completed(TIMEOUT)
    110             self.print_loopback_result(video_codec)
    111 
    112     def print_loopback_result(self, video_codec):
    113         """Prints loopback results (unless we failed to retrieve them).
    114 
    115         @param video_codec: video codec to use.
    116         @raises TestError if the test failed outright.
    117         """
    118         status = self.tab.EvaluateJavaScript('getStatus()')
    119         if status != 'ok-done':
    120             raise error.TestFail('Failed: %s' % status)
    121 
    122         results = self.tab.EvaluateJavaScript('getResults()')
    123         logging.info('Camera Type: %s', results['cameraType'])
    124         logging.info('PeerConnectionstats: %s', results['peerConnectionStats'])
    125         logging.info('FrameStats: %s', results['frameStats'])
    126 
    127         pc_stats = results.get('peerConnectionStats')
    128         if not pc_stats:
    129             raise error.TestFail('Peer Connection Stats is empty')
    130         self.output_perf_value(
    131                 description='max_input_fps_%s' % video_codec,
    132                 value=pc_stats[1], units='fps', higher_is_better=True)
    133         self.output_perf_value(
    134                 description='max_sent_fps_%s' % video_codec,
    135                 value=pc_stats[4], units='fps', higher_is_better=True)
    136 
    137         frame_stats = results.get('frameStats')
    138         if not frame_stats:
    139             raise error.TestFail('Frame Stats is empty')
    140 
    141         self.output_perf_value(
    142                 description='black_frames_%s' % video_codec,
    143                 value=frame_stats['numBlackFrames'],
    144                 units='frames', higher_is_better=False)
    145         self.output_perf_value(
    146                 description='frozen_frames_%s' % video_codec,
    147                 value=frame_stats['numFrozenFrames'],
    148                 units='frames', higher_is_better=False)
    149         self.output_perf_value(
    150                 description='total_num_frames_%s' % video_codec,
    151                 value=frame_stats['numFrames'],
    152                 units='frames', higher_is_better=True)
    153