1# Copyright (c) 2014 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
7import re
8
9from autotest_lib.client.bin import test, utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib import file_utils
12from autotest_lib.client.common_lib.cros import chrome
13from autotest_lib.client.cros.video import device_capability
14from autotest_lib.client.cros.video import helper_logger
15
16
17# Chrome flags to use fake camera and skip camera permission.
18EXTRA_BROWSER_ARGS = ['--use-fake-device-for-media-stream',
19                      '--use-fake-ui-for-media-stream']
20FAKE_FILE_ARG = '--use-file-for-fake-video-capture="%s"'
21DOWNLOAD_BASE = 'http://commondatastorage.googleapis.com/chromiumos-test-assets-public/crowd/'
22VIDEO_NAME = 'crowd720_25frames.y4m'
23
24RTC_VIDEO_ENCODE = 'Media.RTCVideoEncoderInitEncodeSuccess'
25RTC_VIDEO_ENCODE_BUCKET = 1
26RTC_ENCODE_PROFILE = 'Media.RTCVideoEncoderProfile'
27RTC_ENCODE_PROFILE_BUCKET = 11
28HISTOGRAMS_URL = 'chrome://histograms/'
29
30class video_ChromeRTCHWEncodeUsed(test.test):
31    """The test verifies HW Encoding for WebRTC video."""
32    version = 1
33
34
35    def start_loopback(self, cr):
36        """
37        Opens WebRTC loopback page.
38
39        @param cr: Autotest Chrome instance.
40        """
41        tab = cr.browser.tabs.New()
42        tab.Navigate(cr.browser.platform.http_server.UrlOf(
43                os.path.join(self.bindir, 'loopback.html')))
44        tab.WaitForDocumentReadyStateToBeComplete()
45
46
47    def assert_hardware_accelerated(self, cr):
48        """
49        Checks if WebRTC decoding is hardware accelerated.
50
51        @param cr: Autotest Chrome instance.
52
53        @raises error.TestError if decoding is not hardware accelerated.
54        """
55        tab = cr.browser.tabs.New()
56        def _histograms_loaded(histogram):
57            """Returns true if histogram is loaded."""
58            tab.Navigate(HISTOGRAMS_URL + histogram)
59            tab.WaitForDocumentReadyStateToBeComplete()
60            return tab.EvaluateJavaScript(
61                    'document.documentElement.innerText.search("%s") != -1'
62                    % histogram)
63
64        def _histogram_success(histogram, bucket):
65            lines = tab.EvaluateJavaScript(
66                    'document.documentElement.innerText').split("\n")
67            lines = [line for line in lines if line.strip()]
68            logging.info('Histograms for %s:', histogram )
69            logging.info(lines)
70            success = False
71            for line in lines:
72                re_string = '^'+ str(bucket) +'\s\s-(.*)100.0%(.*)'
73                if re.match(re_string, line):
74                    success = True
75                    break
76            if not success:
77                raise error.TestError(
78                        '{0} didn\'t show up or is not 100%'
79                        ' successful.'.format(histogram))
80
81        for histogram, bucket in [(RTC_VIDEO_ENCODE, RTC_VIDEO_ENCODE_BUCKET),
82                (RTC_ENCODE_PROFILE, RTC_ENCODE_PROFILE_BUCKET)]:
83            utils.poll_for_condition(
84                    lambda: _histograms_loaded(histogram),
85                    timeout=5,
86                    exception=error.TestError(
87                            'Cannot find %s histogram.' % histogram),
88                    sleep_interval=1)
89            _histogram_success(histogram, bucket)
90
91    @helper_logger.video_log_wrapper
92    def run_once(self, capability, arc_mode=None):
93        if not device_capability.DeviceCapability().have_capability(capability):
94            logging.warning("Missing Capability: %s" % capability)
95            return
96
97        # Download test video.
98        url = DOWNLOAD_BASE + VIDEO_NAME
99        local_path = os.path.join(self.bindir, VIDEO_NAME)
100        file_utils.download_file(url, local_path)
101
102        # Start chrome with test flags.
103        EXTRA_BROWSER_ARGS.append(FAKE_FILE_ARG % local_path)
104        EXTRA_BROWSER_ARGS.append(helper_logger.chrome_vmodule_flag())
105        with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS,
106                           arc_mode=arc_mode,
107                           init_network_controller=True) as cr:
108            # Open WebRTC loopback page.
109            cr.browser.platform.SetHTTPServerDirectories(self.bindir)
110            self.start_loopback(cr)
111
112            # Make sure decode is hardware accelerated.
113            self.assert_hardware_accelerated(cr)
114