summaryrefslogtreecommitdiff
path: root/chromium/media/tools
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/media/tools
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/media/tools')
-rwxr-xr-xchromium/media/tools/bug_hunter/bug_hunter.py380
-rw-r--r--chromium/media/tools/bug_hunter/bug_hunter_test.py96
-rw-r--r--chromium/media/tools/bug_hunter/bug_hunter_unittest.py182
-rwxr-xr-xchromium/media/tools/constrained_network_server/cn.py123
-rwxr-xr-xchromium/media/tools/constrained_network_server/cns.py456
-rwxr-xr-xchromium/media/tools/constrained_network_server/cns_test.py265
-rw-r--r--chromium/media/tools/constrained_network_server/traffic_control.py354
-rwxr-xr-xchromium/media/tools/constrained_network_server/traffic_control_test.py173
-rwxr-xr-xchromium/media/tools/constrained_network_server/traffic_control_unittest.py145
-rw-r--r--chromium/media/tools/demuxer_bench/demuxer_bench.cc240
-rw-r--r--chromium/media/tools/layout_tests/README93
-rw-r--r--chromium/media/tools/layout_tests/bug.py61
-rw-r--r--chromium/media/tools/layout_tests/graph/graph.html53
-rwxr-xr-xchromium/media/tools/layout_tests/layouttest_analyzer.py479
-rw-r--r--chromium/media/tools/layout_tests/layouttest_analyzer_helpers.py596
-rwxr-xr-xchromium/media/tools/layout_tests/layouttest_analyzer_helpers_unittest.py212
-rwxr-xr-xchromium/media/tools/layout_tests/layouttest_analyzer_runner.py169
-rw-r--r--chromium/media/tools/layout_tests/layouttests.py244
-rwxr-xr-xchromium/media/tools/layout_tests/layouttests_unittest.py47
-rw-r--r--chromium/media/tools/layout_tests/result/2011-08-19-111891
-rw-r--r--chromium/media/tools/layout_tests/result/2011-08-19-211883
-rw-r--r--chromium/media/tools/layout_tests/result/2011-09-11-182033
-rw-r--r--chromium/media/tools/layout_tests/result/2011-09-11-192047
-rw-r--r--chromium/media/tools/layout_tests/test_data/base1877
-rw-r--r--chromium/media/tools/layout_tests/test_data/graph.html.bak53
-rw-r--r--chromium/media/tools/layout_tests/test_data/less1869
-rw-r--r--chromium/media/tools/layout_tests/test_data/more1883
-rw-r--r--chromium/media/tools/layout_tests/test_data/more_te_info1891
-rw-r--r--chromium/media/tools/layout_tests/test_expectations.py123
-rw-r--r--chromium/media/tools/layout_tests/test_expectations_history.py128
-rwxr-xr-xchromium/media/tools/layout_tests/test_expectations_history_unittest.py70
-rwxr-xr-xchromium/media/tools/layout_tests/test_expectations_unittest.py42
-rw-r--r--chromium/media/tools/layout_tests/testname/media.csv25
-rw-r--r--chromium/media/tools/layout_tests/trend_graph.py76
-rwxr-xr-xchromium/media/tools/layout_tests/trend_graph_unittest.py40
-rw-r--r--chromium/media/tools/media_bench/media_bench.cc588
-rw-r--r--chromium/media/tools/player_x11/data_source_logger.cc69
-rw-r--r--chromium/media/tools/player_x11/data_source_logger.h41
-rw-r--r--chromium/media/tools/player_x11/gl_video_renderer.cc257
-rw-r--r--chromium/media/tools/player_x11/gl_video_renderer.h43
-rw-r--r--chromium/media/tools/player_x11/player_x11.cc309
-rw-r--r--chromium/media/tools/player_x11/x11_video_renderer.cc212
-rw-r--r--chromium/media/tools/player_x11/x11_video_renderer.h47
-rw-r--r--chromium/media/tools/seek_tester/seek_tester.cc112
-rw-r--r--chromium/media/tools/shader_bench/cpu_color_painter.cc96
-rw-r--r--chromium/media/tools/shader_bench/cpu_color_painter.h33
-rw-r--r--chromium/media/tools/shader_bench/gpu_color_painter.cc122
-rw-r--r--chromium/media/tools/shader_bench/gpu_color_painter.h35
-rw-r--r--chromium/media/tools/shader_bench/gpu_painter.cc92
-rw-r--r--chromium/media/tools/shader_bench/gpu_painter.h44
-rw-r--r--chromium/media/tools/shader_bench/painter.cc26
-rw-r--r--chromium/media/tools/shader_bench/painter.h39
-rw-r--r--chromium/media/tools/shader_bench/shader_bench.cc162
-rw-r--r--chromium/media/tools/shader_bench/window.cc19
-rw-r--r--chromium/media/tools/shader_bench/window.h61
-rw-r--r--chromium/media/tools/shader_bench/window_linux.cc87
-rw-r--r--chromium/media/tools/shader_bench/window_win.cc134
57 files changed, 22927 insertions, 0 deletions
diff --git a/chromium/media/tools/bug_hunter/bug_hunter.py b/chromium/media/tools/bug_hunter/bug_hunter.py
new file mode 100755
index 00000000000..19a2f8f75f8
--- /dev/null
+++ b/chromium/media/tools/bug_hunter/bug_hunter.py
@@ -0,0 +1,380 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This script queries the Chromium issue tracker and e-mails the results.
+
+It queries issue tracker using Issue Tracker API. The query
+parameters can be specified by command-line arguments. For example, with the
+following command:
+
+ 'python bug_hunter.py -q video Status:Unconfirmed OR audio Status:Unconfirmed
+ -s sender@chromium.org -r receiver@chromium.org -v 100 -u days'
+
+You will find all 'Unconfirmed' issues created in the last 100 days containing
+'video' or 'audio' in their content/comments. The content of these issues are
+sent to receiver@chromium.org.
+
+TODO(imasaki): users can specify the interval as say: "100d" for "100 days".
+
+There are two limitations in the current implementation of issue tracker API
+and UI:
+* only outermost OR is valid. For example, the query
+ 'video OR audio Status:Unconfirmed' is translated into
+ 'video OR (audio AND Status:Unconfirmed)'
+* brackets are not supported. For example, the query
+ '(video OR audio) Status:Unconfirmed' does not work.
+
+You need to install following to run this script
+ gdata-python-client (http://code.google.com/p/gdata-python-client/)
+ rfc3339.py (http://henry.precheur.org/projects/rfc3339)
+
+Links:
+* Chromium issue tracker: http://code.google.com/p/chromium/issues/list
+* Issue tracker API: http://code.google.com/p/support/wiki/IssueTrackerAPI
+* Search tips for the issue tracker:
+ http://code.google.com/p/chromium/issues/searchtips
+"""
+
+import csv
+import datetime
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+import logging
+from operator import itemgetter
+import optparse
+import re
+import smtplib
+import socket
+import sys
+import urllib
+
+try:
+ import gdata.data
+ import gdata.projecthosting.client
+except ImportError:
+ logging.error('gdata-client needs to be installed. Please install\n'
+ 'and try again (http://code.google.com/p/gdata-python-client/)')
+ sys.exit(1)
+
+try:
+ import rfc3339
+except ImportError:
+ logging.error('rfc3339 needs to be installed. Please install\n'
+ 'and try again (http://henry.precheur.org/projects/rfc3339)')
+ sys.exit(1)
+
+# A list of default values.
+_DEFAULT_INTERVAL_UNIT = 'hours'
+_DEFAULT_ISSUE_ELEMENT_IN_EMAIL = ('author', 'status', 'state', 'content',
+ 'comments', 'labels', 'urls')
+_DEFAULT_PROJECT_NAME = 'chromium'
+_DEFAULT_QUERY_TITLE = 'potential media bugs'
+_DEFAULT_QUERY = ('video -has:Feature -has:Owner -label:nomedia '
+ 'status:Unconfirmed OR audio -has:Feature -has:Owner '
+ '-label:nomedia status:Unconfirmed')
+_DEFAULT_OUTPUT_FILENAME = 'output.csv'
+_DETAULT_MAX_COMMENTS = 1000
+
+_INTERVAL_UNIT_CHOICES = ('hours', 'days', 'weeks')
+
+# URLs in this list are excluded from URL extraction from bug
+# content/comments. Each list element should not contain the url ending in
+# '/'. For example, the element should be 'http://www.google.com' but not
+# 'http://www.google.com/'
+_URL_EXCLUSION_LIST = ('http://www.youtube.com/html5',
+ 'http://www.google.com')
+_ISSUE_ELEMENT_IN_EMAIL_CHOICES = ('issue_id', 'author', 'status', 'state',
+ 'content', 'comments', 'labels', 'urls',
+ 'mstone')
+
+
+def ParseArgs():
+ """Returns options dictionary from parsed command line arguments."""
+ parser = optparse.OptionParser()
+
+ parser.add_option('-e', '--email-entries',
+ help=('A comma-separated list of issue entries that are '
+ 'sent in the email content. '
+ 'Possible strings are %s. Default: %%default.' %
+ ', '.join(_ISSUE_ELEMENT_IN_EMAIL_CHOICES)),
+ default=','.join(_DEFAULT_ISSUE_ELEMENT_IN_EMAIL))
+ parser.add_option('-l', '--max-comments',
+ help=('The maximum number of comments returned for each '
+ 'issue in a reverse chronological order. '
+ 'Default: %default.'),
+ type='int', default=_DETAULT_MAX_COMMENTS)
+ parser.add_option('-o', '--output-filename',
+ help=('Filename for result output in CSV format. '
+ 'Default: %default.'),
+ default=_DEFAULT_OUTPUT_FILENAME, metavar='FILE')
+ parser.add_option('-p', '--project-name', default=_DEFAULT_PROJECT_NAME,
+ help='Project name string. Default: %default')
+ parser.add_option('-q', '--query', default=_DEFAULT_QUERY,
+ help=('Query to be used to find bugs. The detail can be '
+ 'found in Chromium Issue tracker page '
+ 'http://code.google.com/p/chromium/issues/searchtips.'
+ ' Default: "%default".'))
+ parser.add_option('-r', '--receiver-email-address',
+ help="Receiver's email address (Required).")
+ parser.add_option('-s', '--sender-email-address',
+ help="Sender's email address (Required).")
+ parser.add_option('-t', '--query-title',
+ default=_DEFAULT_QUERY_TITLE, dest='query_title',
+ help=('Query title string used in the subject of the '
+ 'result email. Default: %default.'))
+ parser.add_option('-u', '--interval_unit', default=_DEFAULT_INTERVAL_UNIT,
+ choices=_INTERVAL_UNIT_CHOICES,
+ help=('Unit name for |interval_value|. Valid options are '
+ '%s. Default: %%default' % (
+ ', '.join(_INTERVAL_UNIT_CHOICES))))
+ parser.add_option('-v', '--interval-value', type='int',
+ help=('Interval value to find bugs. '
+ 'The script looks for bugs during '
+ 'that interval (up to now). This option is used in '
+ 'conjunction with |--interval_unit| option. '
+ 'The script looks for all bugs if this is not '
+ 'specified.'))
+
+ options = parser.parse_args()[0]
+
+ options.email_entries = options.email_entries.split(',')
+ options.email_entries = [entry for entry in options.email_entries
+ if entry in _ISSUE_ELEMENT_IN_EMAIL_CHOICES]
+ if not options.email_entries:
+ logging.warning('No issue elements in email in option. '
+ 'Default email entries will be used.')
+ options.email_entries = _DEFAULT_ISSUE_ELEMENT_IN_EMAIL
+ logging.info('The following is the issue elements in email: %s ' + (
+ ', '.join(options.email_entries)))
+ return options
+
+
+class BugHunter(object):
+ """This class queries issue trackers and e-mails the results."""
+
+ _ISSUE_SEARCH_LINK_BASE = ('http://code.google.com/p/chromium/issues/list?'
+ 'can=2&colspec=ID+Pri+Mstone+ReleaseBlock+Area'
+ '+Feature+Status+Owner+Summary&cells=tiles'
+ '&sort=-id')
+ # TODO(imasaki): Convert these into template library.
+ _EMAIL_ISSUE_TEMPLATE = ('<li><a href="http://crbug.com/%(issue_id)s">'
+ '%(issue_id)s %(title)s</a> ')
+ _EMAIL_SUBJECT_TEMPLATE = ('BugHunter found %(n_issues)d %(query_title)s '
+ 'bug%(plural)s%(time_msg)s!')
+ _EMAIL_MSG_TEMPLATE = ('<a href="%(link_base)s&q=%(unquote_query_text)s">'
+ 'Used Query</a>: %(query_text)s<br><br>'
+ 'The number of issues : %(n_issues)d<br>'
+ '<ul>%(issues)s</ul>')
+
+ def __init__(self, options):
+ """Sets up initial state for Bug Hunter.
+
+ Args:
+ options: Command-line options.
+ """
+ self._client = gdata.projecthosting.client.ProjectHostingClient()
+ self._options = options
+ self._issue_template = BugHunter._EMAIL_ISSUE_TEMPLATE
+ for entry in options.email_entries:
+ self._issue_template += '%%(%s)s ' % entry
+ self._issue_template += '</li>'
+
+ def GetComments(self, issue_id, max_comments):
+ """Get comments for a issue.
+
+ Args:
+ issue_id: Issue id for each issue in the issue tracker.
+ max_comments: The maximum number of comments to be returned. The comments
+ are returned in a reverse chronological order.
+
+ Returns:
+ A list of (author name, comments, updated time) tuples.
+ """
+ comments_feed = self._client.get_comments(self._options.project_name,
+ issue_id)
+ comment_list = [(comment.content.text, comment.author[0].name.text,
+ comment.updated.text)
+ for comment
+ in list(reversed(comments_feed.entry))[0:max_comments]]
+ return comment_list
+
+ def GetIssues(self):
+ """Get issues from issue tracker and return them.
+
+ Returns:
+ A list of issues in descending order by issue_id. Each element in the
+ list is a dictionary where the keys are 'issue_id', 'title', 'author',
+ 'status', 'state', 'content', 'comments', 'labels', 'urls'.
+ Returns an empty list when there is no matching issue.
+ """
+ min_time = None
+ if self._options.interval_value:
+ # Issue Tracker Data API uses RFC 3339 timestamp format, For example:
+ # 2005-08-09T10:57:00-08:00
+ # (http://code.google.com/p/support/wiki/IssueTrackerAPIPython)
+ delta = datetime.timedelta(
+ **{self._options.interval_unit: self._options.interval_value})
+ dt = datetime.datetime.now() - delta
+ min_time = rfc3339.rfc3339(dt)
+
+ query = gdata.projecthosting.client.Query(text_query=self._options.query,
+ max_results=1000,
+ published_min=min_time)
+
+ feed = self._client.get_issues(self._options.project_name, query=query)
+ if not feed.entry:
+ logging.info('No issues available to match query %s.',
+ self._options.query)
+ return []
+ issues = []
+ for entry in feed.entry:
+ # The fully qualified id is a URL. We just want the number.
+ issue_id = entry.id.text.split('/')[-1]
+ if not issue_id.isdigit():
+ logging.warning('Issue_id is not correct: %s. Skipping.', issue_id)
+ continue
+ label_list = [label.text for label in entry.label]
+ comments = ''
+ if 'comments' in self._options.email_entries:
+ comments = ''.join(
+ [''.join(comment) if not comment else ''
+ for comment
+ in self.GetComments(issue_id, self._options.max_comments)])
+ content = BugHunterUtils.StripHTML(entry.content.text)
+ url_list = list(
+ set(re.findall(r'(https?://\S+)', content + comments)))
+ url_list = [url for url in url_list
+ if not url.rstrip('/') in _URL_EXCLUSION_LIST]
+ mstone = ''
+ r = re.compile(r'Mstone-(\d*)')
+ for label in label_list:
+ m = r.search(label)
+ if m:
+ mstone = m.group(1)
+ issues.append(
+ {'issue_id': issue_id, 'title': entry.title.text,
+ 'author': entry.author[0].name.text,
+ 'status': entry.status.text if entry.status is not None else '',
+ 'state': entry.state.text if entry.state is not None else '',
+ 'content': content, 'mstone': mstone, 'comments': comments,
+ 'labels': label_list, 'urls': url_list})
+ return sorted(issues, key=itemgetter('issue_id'), reverse=True)
+
+ def _SetUpEmailSubjectMsg(self, issues):
+ """Set up email subject and its content.
+
+ Args:
+ issues: Please refer to the return value in GetIssues().
+
+ Returns:
+ A tuple of two strings (email subject and email content).
+ """
+ time_msg = ''
+ if self._options.interval_value:
+ time_msg = ' in the past %s %s%s' % (
+ self._options.interval_value, self._options.interval_unit[:-1],
+ 's' if self._options.interval_value > 1 else '')
+ subject = BugHunter._EMAIL_SUBJECT_TEMPLATE % {
+ 'n_issues': len(issues),
+ 'query_title': self._options.query_title,
+ 'plural': 's' if len(issues) > 1 else '',
+ 'time_msg': time_msg}
+ content = BugHunter._EMAIL_MSG_TEMPLATE % {
+ 'link_base': BugHunter._ISSUE_SEARCH_LINK_BASE,
+ 'unquote_query_text': urllib.quote(self._options.query),
+ 'query_text': self._options.query,
+ 'n_issues': len(issues),
+ 'issues': ''.join(
+ [self._issue_template % issue for issue in issues])}
+ return (subject, content)
+
+ def SendResultEmail(self, issues):
+ """Send result email.
+
+ Args:
+ issues: Please refer to the return value in GetIssues().
+ """
+ subject, content = self._SetUpEmailSubjectMsg(issues)
+ BugHunterUtils.SendEmail(
+ content, self._options.sender_email_address,
+ self._options.receiver_email_address, subject)
+
+ def WriteIssuesToFileInCSV(self, issues, filename):
+ """Write issues to a file in CSV format.
+
+ Args:
+ issues: Please refer to the return value in GetIssues().
+ filename: File name for CSV file.
+ """
+ with open(filename, 'w') as f:
+ writer = csv.writer(f)
+ # Write header first.
+ writer.writerow(issues[0].keys())
+ for issue in issues:
+ writer.writerow(
+ [unicode(value).encode('utf-8') for value in issue.values()])
+
+
+class BugHunterUtils(object):
+ """Utility class for Bug Hunter."""
+
+ @staticmethod
+ def StripHTML(string_with_html):
+ """Strip HTML tags from string.
+
+ Args:
+ string_with_html: A string with HTML tags.
+
+ Returns:
+ A string without HTML tags.
+ """
+ return re.sub('<[^<]+?>', '', string_with_html)
+
+ @staticmethod
+ def SendEmail(message, sender_email_address, receivers_email_address,
+ subject):
+ """Send email using localhost's mail server.
+
+ Args:
+ message: Email message to be sent.
+ sender_email_address: Sender's email address.
+ receivers_email_address: Receiver's email address.
+ subject: Email subject.
+
+ Returns:
+ True if successful; False, otherwise.
+ """
+ try:
+ html = '<html><head></head><body>%s</body></html>' % message
+ msg = MIMEMultipart('alternative')
+ msg['Subject'] = subject
+ msg['From'] = sender_email_address
+ msg['To'] = receivers_email_address
+ msg.attach(MIMEText(html.encode('utf-8'), 'html', _charset='utf-8'))
+ smtp_obj = smtplib.SMTP('localhost')
+ smtp_obj.sendmail(sender_email_address, receivers_email_address,
+ msg.as_string())
+ logging.info('Successfully sent email.')
+ smtp_obj.quit()
+ return True
+ except smtplib.SMTPException:
+ logging.exception('Authentication failed, unable to send email.')
+ except (socket.gaierror, socket.error, socket.herror):
+ logging.exception('Unable to send email.')
+ return False
+
+
+def Main():
+ ops = ParseArgs()
+ bh = BugHunter(ops)
+ issues = bh.GetIssues()
+ if issues and ops.sender_email_address and ops.receiver_email_address:
+ bh.SendResultEmail(issues)
+ if issues:
+ bh.WriteIssuesToFileInCSV(issues, ops.output_filename)
+
+
+if __name__ == '__main__':
+ Main()
diff --git a/chromium/media/tools/bug_hunter/bug_hunter_test.py b/chromium/media/tools/bug_hunter/bug_hunter_test.py
new file mode 100644
index 00000000000..0dafd8ab537
--- /dev/null
+++ b/chromium/media/tools/bug_hunter/bug_hunter_test.py
@@ -0,0 +1,96 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Integration tests for bug hunter."""
+
+import csv
+from optparse import Values
+import os
+import unittest
+
+from bug_hunter import BugHunter
+
+try:
+ import gdata.data
+ import gdata.projecthosting.client
+except ImportError:
+ logging.error('gdata-client needs to be installed. Please install\n'
+ 'and try again (http://code.google.com/p/gdata-python-client/)')
+ sys.exit(1)
+
+
+class BugHunterTest(unittest.TestCase):
+ """Unit tests for the Bug Hunter class."""
+ _TEST_FILENAME = 'test.csv'
+
+ def _CleanTestFile(self):
+ if os.path.exists(self._TEST_FILENAME):
+ os.remove(self._TEST_FILENAME)
+
+ def setUp(self):
+ self._CleanTestFile()
+
+ def tearDown(self):
+ self._CleanTestFile()
+
+ def _GetIssue(self):
+ return [{'issue_id': '0', 'title': 'title', 'author': 'author',
+ 'status': 'status', 'state': 'state', 'content': 'content',
+ 'comments': [], 'labels': [], 'urls': []}]
+
+ def _GetDefaultOption(self, set_10_days_ago, query='steps'):
+ ops = Values()
+ ops.query = query
+ if set_10_days_ago:
+ ops.interval_value = 10
+ ops.interval_unit = 'days'
+ else:
+ ops.interval_value = None
+ ops.email_entries = ['comments']
+ ops.project_name = 'chromium'
+ ops.query_title = 'query title'
+ ops.max_comments = None
+ return ops
+
+ def testGetIssueReturnedIssue(self):
+ bh = BugHunter(
+ self._GetDefaultOption(False,
+ query=('audio opened-after:2010/10/10'
+ ' opened-before:2010/10/20')))
+ self.assertEquals(len(bh.GetIssues()), 18)
+
+ def testGetIssueReturnedIssueWithStatus(self):
+ ops = self._GetDefaultOption(False)
+ ops.query = 'Feature:Media* Status:Unconfirmed'
+ issues = BugHunter(ops).GetIssues()
+ for issue in issues:
+ self.assertEquals(issue['status'], 'Unconfirmed')
+
+ def testGetIssueReturnNoIssue(self):
+ ops = self._GetDefaultOption(True)
+ ops.query = 'thisshouldnotmatchpleaseignorethis*'
+ self.assertFalse(BugHunter(ops).GetIssues())
+
+ def testGetComments(self):
+ comments = BugHunter(self._GetDefaultOption(False)).GetComments(100000, 2)
+ self.assertEquals(len(comments), 2)
+ expected_comments = [(None, 'rby...@chromium.org',
+ '2011-10-31T19:54:40.000Z'),
+ (None, 'backer@chromium.org',
+ '2011-10-14T13:59:37.000Z')]
+ self.assertEquals(comments, expected_comments)
+
+ def testWriteIssuesToFileInCSV(self):
+ ops = self._GetDefaultOption(False)
+ bh = BugHunter(ops)
+ bh.WriteIssuesToFileInCSV(self._GetIssue(), self._TEST_FILENAME)
+
+ with open(self._TEST_FILENAME, 'r') as f:
+ reader = csv.reader(f)
+ self.assertEquals(reader.next(), ['status', 'content', 'state',
+ 'issue_id', 'urls', 'title', 'labels',
+ 'author', 'comments'])
+ self.assertEquals(reader.next(), ['status', 'content', 'state', '0',
+ '[]', 'title', '[]', 'author', '[]'])
+ self.assertRaises(StopIteration, reader.next)
diff --git a/chromium/media/tools/bug_hunter/bug_hunter_unittest.py b/chromium/media/tools/bug_hunter/bug_hunter_unittest.py
new file mode 100644
index 00000000000..0cb11b63bb2
--- /dev/null
+++ b/chromium/media/tools/bug_hunter/bug_hunter_unittest.py
@@ -0,0 +1,182 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit Tests for bug hunter."""
+
+import logging
+from optparse import Values
+import smtplib
+import sys
+import unittest
+
+from bug_hunter import BugHunter
+from bug_hunter import BugHunterUtils
+
+try:
+ import atom.data
+ import gdata.data
+ import gdata.projecthosting.client
+except ImportError:
+ logging.error('gdata-client needs to be installed. Please install\n'
+ 'and try again (http://code.google.com/p/gdata-python-client/)')
+ sys.exit(1)
+
+
+class MockClient(object):
+ """A mock class for gdata.projecthosting.client.ProjectHostingClient.
+
+ Mocking the very simple method invocations for get_issues() and
+ get_comments().
+ """
+
+ def _CreateIssues(self, n_issues):
+ feed = gdata.projecthosting.data.IssuesFeed()
+ for i in xrange(n_issues):
+ feed.entry.append(gdata.projecthosting.data.IssueEntry(
+ title=atom.data.Title(text='title'),
+ content=atom.data.Content(text='http://www.content.com'),
+ id=atom.data.Id(text='/' + str(i)),
+ status=gdata.projecthosting.data.Status(text='Unconfirmed'),
+ state=gdata.projecthosting.data.State(text='open'),
+ label=[gdata.projecthosting.data.Label('label1')],
+ author=[atom.data.Author(name=atom.data.Name(text='author'))]))
+ return feed
+
+ def get_issues(self, project_name, query):
+ """Get issues using mock object without calling the issue tracker API.
+
+ Based on query argument, this returns the dummy issues. The number of
+ dummy issues are specified in query.text_query.
+
+ Args:
+ project_name: A string for project name in the issue tracker.
+ query: A query object for querying the issue tracker.
+
+ Returns:
+ A IssuesFeed object that contains a simple test issue.
+ """
+ n_issues = 1
+ if query.text_query.isdigit():
+ n_issues = int(query.text_query)
+ return self._CreateIssues(n_issues)
+
+ def get_comments(self, project_name, issue_id):
+ """Get comments using mock object without calling the issue tracker API.
+
+ Args:
+ project_name: A string for project name in the issue tracker.
+ issue_id: Issue_id string.
+
+ Returns:
+ A CommentsFeed object that contains a simple test comment.
+ """
+ feed = gdata.projecthosting.data.CommentsFeed()
+ feed.entry = [gdata.projecthosting.data.CommentEntry(
+ id=atom.data.Id(text='/0'),
+ content=atom.data.Content(text='http://www.comments.com'),
+ updated=atom.data.Updated(text='Updated'),
+ author=[atom.data.Author(name=atom.data.Name(text='cauthor'))])]
+ return feed
+
+
+class BugHunterUnitTest(unittest.TestCase):
+ """Unit tests for the Bug Hunter class."""
+
+ def setUp(self):
+ self._old_client = gdata.projecthosting.client.ProjectHostingClient
+ gdata.projecthosting.client.ProjectHostingClient = MockClient
+
+ def tearDown(self):
+ gdata.projecthosting.client.ProjectHostingClient = self._old_client
+
+ def _GetDefaultOption(self, set_10_days_ago, query='steps'):
+ ops = Values()
+ ops.query = query
+ if set_10_days_ago:
+ ops.interval_value = 10
+ ops.interval_unit = 'days'
+ else:
+ ops.interval_value = None
+ ops.email_entries = ['comments']
+ ops.project_name = 'chromium'
+ ops.query_title = 'query title'
+ ops.max_comments = None
+ return ops
+
+ def _GetIssue(self, n_issues):
+ issues = []
+ for i in xrange(n_issues):
+ issues.append({'issue_id': str(i), 'title': 'title', 'author': 'author',
+ 'status': 'status', 'state': 'state',
+ 'content': 'content', 'comments': [],
+ 'labels': [], 'urls': []})
+ return issues
+
+ def testSetUpEmailSubjectMsg(self):
+ bh = BugHunter(self._GetDefaultOption(False))
+ subject, content = bh._SetUpEmailSubjectMsg(self._GetIssue(1))
+ self.assertEquals(subject,
+ 'BugHunter found 1 query title bug!')
+ self.assertEquals(content,
+ ('<a href="http://code.google.com/p/chromium/issues/'
+ 'list?can=2&colspec=ID+Pri+Mstone+ReleaseBlock+Area+'
+ 'Feature+Status+Owner+Summary&cells=tiles&sort=-id&'
+ 'q=steps">Used Query</a>: steps<br><br>The number of '
+ 'issues : 1<br><ul><li><a href="http://crbug.com/0">0 '
+ 'title</a> [] </li></ul>'))
+
+ def testSetUpEmailSubjectMsgMultipleIssues(self):
+ bh = BugHunter(self._GetDefaultOption(False))
+ subject, content = bh._SetUpEmailSubjectMsg(self._GetIssue(2))
+ self.assertEquals(subject,
+ 'BugHunter found 2 query title bugs!')
+
+ def testSetUpEmailSubjectMsgWith10DaysAgoAndAssertSubject(self):
+ bh = BugHunter(self._GetDefaultOption(True))
+ subject, _ = bh._SetUpEmailSubjectMsg(self._GetIssue(1))
+ self.assertEquals(subject,
+ ('BugHunter found 1 query title bug in the past 10 '
+ 'days!'))
+
+ def testGetIssuesWithMockClient(self):
+ bh = BugHunter(self._GetDefaultOption(False,
+ query=('dummy')))
+ expected_issues = [{'issue_id': '0', 'title': 'title', 'author': 'author',
+ 'status': 'Unconfirmed', 'state': 'open',
+ 'content': 'http://www.content.com',
+ 'comments': '', 'labels': ['label1'],
+ 'urls': ['http://www.content.com']}]
+ self.assertEquals(expected_issues, bh.GetIssues())
+
+
+class MockSmtp(object):
+ """A mock class for SMTP."""
+
+ def __init__(self, server):
+ pass
+
+ def sendmail(self, sender_email_address, receivers_email_addresses,
+ msg):
+ # TODO(imasaki): Do something here.
+ return True
+
+ def quit(self):
+ pass
+
+
+class BugHunterUtilsTest(unittest.TestCase):
+ """Unit tests for the Bug Hunter utility."""
+
+ def testStripHTML(self):
+ self.assertEquals(BugHunterUtils.StripHTML('<p>X</p>'), 'X')
+
+ def testStripHTMLEmpty(self):
+ self.assertEquals(BugHunterUtils.StripHTML(''), '')
+
+ def testSendEmail(self):
+ smtplib.SMTP = MockSmtp
+ self.assertEqual(BugHunterUtils.SendEmail('message', 'sender_email_address',
+ 'receivers_email_addresses',
+ 'subject'),
+ True)
diff --git a/chromium/media/tools/constrained_network_server/cn.py b/chromium/media/tools/constrained_network_server/cn.py
new file mode 100755
index 00000000000..fe5781cfad7
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/cn.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A script for configuring constraint networks.
+
+Sets up a constrained network configuration on a specific port. Traffic on this
+port will be redirected to another local server port.
+
+The configuration includes bandwidth, latency, and packet loss.
+"""
+
+import collections
+import logging
+import optparse
+import traffic_control
+
+# Default logging is ERROR. Use --verbose to enable DEBUG logging.
+_DEFAULT_LOG_LEVEL = logging.ERROR
+
+Dispatcher = collections.namedtuple('Dispatcher', ['dispatch', 'requires_ports',
+ 'desc'])
+
+# Map of command names to traffic_control functions.
+COMMANDS = {
+ # Adds a new constrained network configuration.
+ 'add': Dispatcher(traffic_control.CreateConstrainedPort,
+ requires_ports=True, desc='Add a new constrained port.'),
+
+ # Deletes an existing constrained network configuration.
+ 'del': Dispatcher(traffic_control.DeleteConstrainedPort,
+ requires_ports=True, desc='Delete a constrained port.'),
+
+ # Deletes all constrained network configurations.
+ 'teardown': Dispatcher(traffic_control.TearDown,
+ requires_ports=False,
+ desc='Teardown all constrained ports.')
+}
+
+
+def _ParseArgs():
+ """Define and parse command-line arguments.
+
+ Returns:
+ tuple as (command, configuration):
+ command: one of the possible commands to setup, delete or teardown the
+ constrained network.
+ configuration: a map of constrained network properties to their values.
+ """
+ parser = optparse.OptionParser()
+
+ indent_first = parser.formatter.indent_increment
+ opt_width = parser.formatter.help_position - indent_first
+
+ cmd_usage = []
+ for s in COMMANDS:
+ cmd_usage.append('%*s%-*s%s' %
+ (indent_first, '', opt_width, s, COMMANDS[s].desc))
+
+ parser.usage = ('usage: %%prog {%s} [options]\n\n%s' %
+ ('|'.join(COMMANDS.keys()), '\n'.join(cmd_usage)))
+
+ parser.add_option('--port', type='int',
+ help='The port to apply traffic control constraints to.')
+ parser.add_option('--server-port', type='int',
+ help='Port to forward traffic on --port to.')
+ parser.add_option('--bandwidth', type='int',
+ help='Bandwidth of the network in kbit/s.')
+ parser.add_option('--latency', type='int',
+ help=('Latency (delay) added to each outgoing packet in '
+ 'ms.'))
+ parser.add_option('--loss', type='int',
+ help='Packet-loss percentage on outgoing packets. ')
+ parser.add_option('--interface', type='string',
+ help=('Interface to setup constraints on. Use "lo" for a '
+ 'local client.'))
+ parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
+ default=False, help='Turn on verbose output.')
+ options, args = parser.parse_args()
+
+ _SetLogger(options.verbose)
+
+ # Check a valid command was entered
+ if not args or args[0].lower() not in COMMANDS:
+ parser.error('Please specify a command {%s}.' % '|'.join(COMMANDS.keys()))
+ user_cmd = args[0].lower()
+
+ # Check if required options are available
+ if COMMANDS[user_cmd].requires_ports:
+ if not (options.port and options.server_port):
+ parser.error('Please provide port and server-port values.')
+
+ config = {
+ 'port': options.port,
+ 'server_port': options.server_port,
+ 'interface': options.interface,
+ 'latency': options.latency,
+ 'bandwidth': options.bandwidth,
+ 'loss': options.loss
+ }
+ return user_cmd, config
+
+
+def _SetLogger(verbose):
+ log_level = _DEFAULT_LOG_LEVEL
+ if verbose:
+ log_level = logging.DEBUG
+ logging.basicConfig(level=log_level, format='%(message)s')
+
+
+def Main():
+ """Get the command and configuration of the network to set up."""
+ user_cmd, config = _ParseArgs()
+
+ try:
+ COMMANDS[user_cmd].dispatch(config)
+ except traffic_control.TrafficControlError as e:
+ logging.error('Error: %s\n\nOutput: %s', e.msg, e.error)
+
+
+if __name__ == '__main__':
+ Main()
diff --git a/chromium/media/tools/constrained_network_server/cns.py b/chromium/media/tools/constrained_network_server/cns.py
new file mode 100755
index 00000000000..58e2ba000d8
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/cns.py
@@ -0,0 +1,456 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Constrained Network Server. Serves files with supplied network constraints.
+
+The CNS exposes a web based API allowing network constraints to be imposed on
+file serving.
+
+TODO(dalecurtis): Add some more docs here.
+
+"""
+
+import logging
+from logging import handlers
+import mimetypes
+import optparse
+import os
+import signal
+import sys
+import threading
+import time
+import urllib
+import urllib2
+
+import traffic_control
+
+try:
+ import cherrypy
+except ImportError:
+ print ('CNS requires CherryPy v3 or higher to be installed. Please install\n'
+ 'and try again. On Linux: sudo apt-get install python-cherrypy3\n')
+ sys.exit(1)
+
+# Add webm file types to mimetypes map since cherrypy's default type is text.
+mimetypes.types_map['.webm'] = 'video/webm'
+
+# Default logging is ERROR. Use --verbose to enable DEBUG logging.
+_DEFAULT_LOG_LEVEL = logging.ERROR
+
+# Default port to serve the CNS on.
+_DEFAULT_SERVING_PORT = 9000
+
+# Default port range for constrained use.
+_DEFAULT_CNS_PORT_RANGE = (50000, 51000)
+
+# Default number of seconds before a port can be torn down.
+_DEFAULT_PORT_EXPIRY_TIME_SECS = 5 * 60
+
+
+class PortAllocator(object):
+ """Dynamically allocates/deallocates ports with a given set of constraints."""
+
+ def __init__(self, port_range, expiry_time_secs=5 * 60):
+ """Sets up initial state for the Port Allocator.
+
+ Args:
+ port_range: Range of ports available for allocation.
+ expiry_time_secs: Amount of time in seconds before constrained ports are
+ cleaned up.
+ """
+ self._port_range = port_range
+ self._expiry_time_secs = expiry_time_secs
+
+ # Keeps track of ports we've used, the creation key, and the last request
+ # time for the port so they can be cached and cleaned up later.
+ self._ports = {}
+
+ # Locks port creation and cleanup. TODO(dalecurtis): If performance becomes
+ # an issue a per-port based lock system can be used instead.
+ self._port_lock = threading.RLock()
+
+ def Get(self, key, new_port=False, **kwargs):
+ """Sets up a constrained port using the requested parameters.
+
+ Requests for the same key and constraints will result in a cached port being
+ returned if possible, subject to new_port.
+
+ Args:
+ key: Used to cache ports with the given constraints.
+ new_port: Whether to create a new port or use an existing one if possible.
+ **kwargs: Constraints to pass into traffic control.
+
+ Returns:
+ None if no port can be setup or the port number of the constrained port.
+ """
+ with self._port_lock:
+ # Check port key cache to see if this port is already setup. Update the
+ # cache time and return the port if so. Performance isn't a concern here,
+ # so just iterate over ports dict for simplicity.
+ full_key = (key,) + tuple(kwargs.values())
+ if not new_port:
+ for port, status in self._ports.iteritems():
+ if full_key == status['key']:
+ self._ports[port]['last_update'] = time.time()
+ return port
+
+ # Cleanup ports on new port requests. Do it after the cache check though
+ # so we don't erase and then setup the same port.
+ if self._expiry_time_secs > 0:
+ self.Cleanup(all_ports=False)
+
+ # Performance isn't really an issue here, so just iterate over the port
+ # range to find an unused port. If no port is found, None is returned.
+ for port in xrange(self._port_range[0], self._port_range[1]):
+ if port in self._ports:
+ continue
+ if self._SetupPort(port, **kwargs):
+ kwargs['port'] = port
+ self._ports[port] = {'last_update': time.time(), 'key': full_key,
+ 'config': kwargs}
+ return port
+
+ def _SetupPort(self, port, **kwargs):
+ """Setup network constraints on port using the requested parameters.
+
+ Args:
+ port: The port number to setup network constraints on.
+ **kwargs: Network constraints to set up on the port.
+
+ Returns:
+ True if setting the network constraints on the port was successful, false
+ otherwise.
+ """
+ kwargs['port'] = port
+ try:
+ cherrypy.log('Setting up port %d' % port)
+ traffic_control.CreateConstrainedPort(kwargs)
+ return True
+ except traffic_control.TrafficControlError as e:
+ cherrypy.log('Error: %s\nOutput: %s' % (e.msg, e.error))
+ return False
+
+ def Cleanup(self, all_ports, request_ip=None):
+ """Cleans up expired ports, or if all_ports=True, all allocated ports.
+
+ By default, ports which haven't been used for self._expiry_time_secs are
+ torn down. If all_ports=True then they are torn down regardless.
+
+ Args:
+ all_ports: Should all ports be torn down regardless of expiration?
+ request_ip: Tear ports matching the IP address regarless of expiration.
+ """
+ with self._port_lock:
+ now = time.time()
+ # Use .items() instead of .iteritems() so we can delete keys w/o error.
+ for port, status in self._ports.items():
+ expired = now - status['last_update'] > self._expiry_time_secs
+ matching_ip = request_ip and status['key'][0].startswith(request_ip)
+ if all_ports or expired or matching_ip:
+ cherrypy.log('Cleaning up port %d' % port)
+ self._DeletePort(port)
+ del self._ports[port]
+
+ def _DeletePort(self, port):
+ """Deletes network constraints on port.
+
+ Args:
+ port: The port number associated with the network constraints.
+ """
+ try:
+ traffic_control.DeleteConstrainedPort(self._ports[port]['config'])
+ except traffic_control.TrafficControlError as e:
+ cherrypy.log('Error: %s\nOutput: %s' % (e.msg, e.error))
+
+
+class ConstrainedNetworkServer(object):
+ """A CherryPy-based HTTP server for serving files with network constraints."""
+
+ def __init__(self, options, port_allocator):
+ """Sets up initial state for the CNS.
+
+ Args:
+ options: optparse based class returned by ParseArgs()
+ port_allocator: A port allocator instance.
+ """
+ self._options = options
+ self._port_allocator = port_allocator
+
+ @cherrypy.expose
+ def Cleanup(self):
+ """Cleans up all the ports allocated using the request IP address.
+
+ When requesting a constrained port, the cherrypy.request.remote.ip is used
+ as a key for that port (in addition to other request parameters). Such
+ ports created for the same IP address are removed.
+ """
+ cherrypy.log('Cleaning up ports allocated by %s.' %
+ cherrypy.request.remote.ip)
+ self._port_allocator.Cleanup(all_ports=False,
+ request_ip=cherrypy.request.remote.ip)
+
+ @cherrypy.expose
+ def ServeConstrained(self, f=None, bandwidth=None, latency=None, loss=None,
+ new_port=False, no_cache=False, **kwargs):
+ """Serves the requested file with the requested constraints.
+
+ Subsequent requests for the same constraints from the same IP will share the
+ previously created port unless new_port equals True. If no constraints
+ are provided the file is served as is.
+
+ Args:
+ f: path relative to http root of file to serve.
+ bandwidth: maximum allowed bandwidth for the provided port (integer
+ in kbit/s).
+ latency: time to add to each packet (integer in ms).
+ loss: percentage of packets to drop (integer, 0-100).
+ new_port: whether to use a new port for this request or not.
+ no_cache: Set reponse's cache-control to no-cache.
+ """
+ if no_cache:
+ response = cherrypy.response
+ response.headers['Pragma'] = 'no-cache'
+ response.headers['Cache-Control'] = 'no-cache'
+
+ # CherryPy is a bit wonky at detecting parameters, so just make them all
+ # optional and validate them ourselves.
+ if not f:
+ raise cherrypy.HTTPError(400, 'Invalid request. File must be specified.')
+
+ # Check existence early to prevent wasted constraint setup.
+ self._CheckRequestedFileExist(f)
+
+ # If there are no constraints, just serve the file.
+ if bandwidth is None and latency is None and loss is None:
+ return self._ServeFile(f)
+
+ constrained_port = self._GetConstrainedPort(
+ f, bandwidth=bandwidth, latency=latency, loss=loss, new_port=new_port,
+ **kwargs)
+
+ # Build constrained URL using the constrained port and original URL
+ # parameters except the network constraints (bandwidth, latency, and loss).
+ constrained_url = self._GetServerURL(f, constrained_port,
+ no_cache=no_cache, **kwargs)
+
+ # Redirect request to the constrained port.
+ cherrypy.log('Redirect to %s' % constrained_url)
+ cherrypy.lib.cptools.redirect(constrained_url, internal=False)
+
+ def _CheckRequestedFileExist(self, f):
+ """Checks if the requested file exists, raises HTTPError otherwise."""
+ if self._options.local_server_port:
+ self._CheckFileExistOnLocalServer(f)
+ else:
+ self._CheckFileExistOnServer(f)
+
+ def _CheckFileExistOnServer(self, f):
+ """Checks if requested file f exists to be served by this server."""
+ # Sanitize and check the path to prevent www-root escapes.
+ sanitized_path = os.path.abspath(os.path.join(self._options.www_root, f))
+ if not sanitized_path.startswith(self._options.www_root):
+ raise cherrypy.HTTPError(403, 'Invalid file requested.')
+ if not os.path.exists(sanitized_path):
+ raise cherrypy.HTTPError(404, 'File not found.')
+
+ def _CheckFileExistOnLocalServer(self, f):
+ """Checks if requested file exists on local server hosting files."""
+ test_url = self._GetServerURL(f, self._options.local_server_port)
+ try:
+ cherrypy.log('Check file exist using URL: %s' % test_url)
+ return urllib2.urlopen(test_url) is not None
+ except Exception:
+ raise cherrypy.HTTPError(404, 'File not found on local server.')
+
+ def _ServeFile(self, f):
+ """Serves the file as an http response."""
+ if self._options.local_server_port:
+ redirect_url = self._GetServerURL(f, self._options.local_server_port)
+ cherrypy.log('Redirect to %s' % redirect_url)
+ cherrypy.lib.cptools.redirect(redirect_url, internal=False)
+ else:
+ sanitized_path = os.path.abspath(os.path.join(self._options.www_root, f))
+ return cherrypy.lib.static.serve_file(sanitized_path)
+
+ def _GetServerURL(self, f, port, **kwargs):
+ """Returns a URL for local server to serve the file on given port.
+
+ Args:
+ f: file name to serve on local server. Relative to www_root.
+ port: Local server port (it can be a configured constrained port).
+ kwargs: extra parameteres passed in the URL.
+ """
+ url = '%s?f=%s&' % (cherrypy.url(), f)
+ if self._options.local_server_port:
+ url = '%s/%s?' % (
+ cherrypy.url().replace('ServeConstrained', self._options.www_root), f)
+
+ url = url.replace(':%d' % self._options.port, ':%d' % port)
+ extra_args = urllib.urlencode(kwargs)
+ if extra_args:
+ url += extra_args
+ return url
+
+ def _GetConstrainedPort(self, f=None, bandwidth=None, latency=None, loss=None,
+ new_port=False, **kwargs):
+ """Creates or gets a port with specified network constraints.
+
+ See ServeConstrained() for more details.
+ """
+ # Validate inputs. isdigit() guarantees a natural number.
+ bandwidth = self._ParseIntParameter(
+ bandwidth, 'Invalid bandwidth constraint.', lambda x: x > 0)
+ latency = self._ParseIntParameter(
+ latency, 'Invalid latency constraint.', lambda x: x >= 0)
+ loss = self._ParseIntParameter(
+ loss, 'Invalid loss constraint.', lambda x: x <= 100 and x >= 0)
+
+ redirect_port = self._options.port
+ if self._options.local_server_port:
+ redirect_port = self._options.local_server_port
+
+ start_time = time.time()
+ # Allocate a port using the given constraints. If a port with the requested
+ # key and kwargs already exist then reuse that port.
+ constrained_port = self._port_allocator.Get(
+ cherrypy.request.remote.ip, server_port=redirect_port,
+ interface=self._options.interface, bandwidth=bandwidth, latency=latency,
+ loss=loss, new_port=new_port, file=f, **kwargs)
+
+ cherrypy.log('Time to set up port %d = %.3fsec.' %
+ (constrained_port, time.time() - start_time))
+
+ if not constrained_port:
+ raise cherrypy.HTTPError(503, 'Service unavailable. Out of ports.')
+ return constrained_port
+
+ def _ParseIntParameter(self, param, msg, check):
+ """Returns integer value of param and verifies it satisfies the check.
+
+ Args:
+ param: Parameter name to check.
+ msg: Message in error if raised.
+ check: Check to verify the parameter value.
+
+ Returns:
+ None if param is None, integer value of param otherwise.
+
+ Raises:
+ cherrypy.HTTPError if param can not be converted to integer or if it does
+ not satisfy the check.
+ """
+ if param:
+ try:
+ int_value = int(param)
+ if check(int_value):
+ return int_value
+ except:
+ pass
+ raise cherrypy.HTTPError(400, msg)
+
+
+def ParseArgs():
+ """Define and parse the command-line arguments."""
+ parser = optparse.OptionParser()
+
+ parser.add_option('--expiry-time', type='int',
+ default=_DEFAULT_PORT_EXPIRY_TIME_SECS,
+ help=('Number of seconds before constrained ports expire '
+ 'and are cleaned up. 0=Disabled. Default: %default'))
+ parser.add_option('--port', type='int', default=_DEFAULT_SERVING_PORT,
+ help='Port to serve the API on. Default: %default')
+ parser.add_option('--port-range', default=_DEFAULT_CNS_PORT_RANGE,
+ help=('Range of ports for constrained serving. Specify as '
+ 'a comma separated value pair. Default: %default'))
+ parser.add_option('--interface', default='eth0',
+ help=('Interface to setup constraints on. Use lo for a '
+ 'local client. Default: %default'))
+ parser.add_option('--socket-timeout', type='int',
+ default=cherrypy.server.socket_timeout,
+ help=('Number of seconds before a socket connection times '
+ 'out. Default: %default'))
+ parser.add_option('--threads', type='int',
+ default=cherrypy._cpserver.Server.thread_pool,
+ help=('Number of threads in the thread pool. Default: '
+ '%default'))
+ parser.add_option('--www-root', default='',
+ help=('Directory root to serve files from. If --local-'
+ 'server-port is used, the path is appended to the '
+ 'redirected URL of local server. Defaults to the '
+ 'current directory (if --local-server-port is not '
+ 'used): %s' % os.getcwd()))
+ parser.add_option('--local-server-port', type='int',
+ help=('Optional local server port to host files.'))
+ parser.add_option('-v', '--verbose', action='store_true', default=False,
+ help='Turn on verbose output.')
+
+ options = parser.parse_args()[0]
+
+ # Convert port range into the desired tuple format.
+ try:
+ if isinstance(options.port_range, str):
+ options.port_range = [int(port) for port in options.port_range.split(',')]
+ except ValueError:
+ parser.error('Invalid port range specified.')
+
+ if options.expiry_time < 0:
+ parser.error('Invalid expiry time specified.')
+
+ # Convert the path to an absolute to remove any . or ..
+ if not options.local_server_port:
+ if not options.www_root:
+ options.www_root = os.getcwd()
+ options.www_root = os.path.abspath(options.www_root)
+
+ _SetLogger(options.verbose)
+
+ return options
+
+
+def _SetLogger(verbose):
+ file_handler = handlers.RotatingFileHandler('cns.log', 'a', 10000000, 10)
+ file_handler.setFormatter(logging.Formatter('[%(threadName)s] %(message)s'))
+
+ log_level = _DEFAULT_LOG_LEVEL
+ if verbose:
+ log_level = logging.DEBUG
+ file_handler.setLevel(log_level)
+
+ cherrypy.log.error_log.addHandler(file_handler)
+ cherrypy.log.access_log.addHandler(file_handler)
+
+
+def Main():
+ """Configure and start the ConstrainedNetworkServer."""
+ options = ParseArgs()
+
+ try:
+ traffic_control.CheckRequirements()
+ except traffic_control.TrafficControlError as e:
+ cherrypy.log(e.msg)
+ return
+
+ cherrypy.config.update({'server.socket_host': '::',
+ 'server.socket_port': options.port})
+
+ if options.threads:
+ cherrypy.config.update({'server.thread_pool': options.threads})
+
+ if options.socket_timeout:
+ cherrypy.config.update({'server.socket_timeout': options.socket_timeout})
+
+ # Setup port allocator here so we can call cleanup on failures/exit.
+ pa = PortAllocator(options.port_range, expiry_time_secs=options.expiry_time)
+
+ try:
+ cherrypy.quickstart(ConstrainedNetworkServer(options, pa))
+ finally:
+ # Disable Ctrl-C handler to prevent interruption of cleanup.
+ signal.signal(signal.SIGINT, lambda signal, frame: None)
+ pa.Cleanup(all_ports=True)
+
+
+if __name__ == '__main__':
+ Main()
diff --git a/chromium/media/tools/constrained_network_server/cns_test.py b/chromium/media/tools/constrained_network_server/cns_test.py
new file mode 100755
index 00000000000..5d794956755
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/cns_test.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for Constrained Network Server."""
+import os
+import signal
+import subprocess
+import tempfile
+import time
+import unittest
+import urllib2
+import cherrypy
+import cns
+import traffic_control
+
+# The local interface to test on.
+_INTERFACE = 'lo'
+
+
+class PortAllocatorTest(unittest.TestCase):
+ """Unit tests for the Port Allocator class."""
+
+ # Expiration time for ports. In mock time.
+ _EXPIRY_TIME = 6
+
+ def setUp(self):
+ # Mock out time.time() to accelerate port expiration testing.
+ self._old_time = time.time
+ self._current_time = 0
+ time.time = lambda: self._current_time
+
+ # TODO(dalecurtis): Mock out actual calls to shadi's port setup.
+ self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, self._EXPIRY_TIME)
+ self._MockTrafficControl()
+
+ def tearDown(self):
+ self._pa.Cleanup(all_ports=True)
+ # Ensure ports are cleaned properly.
+ self.assertEquals(self._pa._ports, {})
+ time.time = self._old_time
+ self._RestoreTrafficControl()
+
+ def _MockTrafficControl(self):
+ self.old_CreateConstrainedPort = traffic_control.CreateConstrainedPort
+ self.old_DeleteConstrainedPort = traffic_control.DeleteConstrainedPort
+ self.old_TearDown = traffic_control.TearDown
+
+ traffic_control.CreateConstrainedPort = lambda config: True
+ traffic_control.DeleteConstrainedPort = lambda config: True
+ traffic_control.TearDown = lambda config: True
+
+ def _RestoreTrafficControl(self):
+ traffic_control.CreateConstrainedPort = self.old_CreateConstrainedPort
+ traffic_control.DeleteConstrainedPort = self.old_DeleteConstrainedPort
+ traffic_control.TearDown = self.old_TearDown
+
+ def testPortAllocator(self):
+ # Ensure Get() succeeds and returns the correct port.
+ self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
+
+ # Call again with the same key and make sure we get the same port.
+ self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
+
+ # Call with a different key and make sure we get a different port.
+ self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+
+ # Update fake time so that ports should expire.
+ self._current_time += self._EXPIRY_TIME + 1
+
+ # Test to make sure cache is checked before expiring ports.
+ self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+
+ # Update fake time so that ports should expire.
+ self._current_time += self._EXPIRY_TIME + 1
+
+ # Request a new port, old ports should be expired, so we should get the
+ # first port in the range. Make sure this is the only allocated port.
+ self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0])
+ self.assertEquals(self._pa._ports.keys(), [cns._DEFAULT_CNS_PORT_RANGE[0]])
+
+ def testPortAllocatorExpiresOnlyCorrectPorts(self):
+ # Ensure Get() succeeds and returns the correct port.
+ self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
+
+ # Stagger port allocation and so we can ensure only ports older than the
+ # expiry time are actually expired.
+ self._current_time += self._EXPIRY_TIME / 2 + 1
+
+ # Call with a different key and make sure we get a different port.
+ self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+
+ # After this sleep the port with key 'test' should expire on the next Get().
+ self._current_time += self._EXPIRY_TIME / 2 + 1
+
+ # Call with a different key and make sure we get the first port.
+ self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0])
+ self.assertEquals(set(self._pa._ports.keys()), set([
+ cns._DEFAULT_CNS_PORT_RANGE[0], cns._DEFAULT_CNS_PORT_RANGE[0] + 1]))
+
+ def testPortAllocatorNoExpiration(self):
+ # Setup PortAllocator w/o port expiration.
+ self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, 0)
+
+ # Ensure Get() succeeds and returns the correct port.
+ self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
+
+ # Update fake time to see if ports expire.
+ self._current_time += self._EXPIRY_TIME
+
+ # Send second Get() which would normally cause ports to expire. Ensure that
+ # the ports did not expire.
+ self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+ self.assertEquals(set(self._pa._ports.keys()), set([
+ cns._DEFAULT_CNS_PORT_RANGE[0], cns._DEFAULT_CNS_PORT_RANGE[0] + 1]))
+
+ def testPortAllocatorCleanMatchingIP(self):
+ # Setup PortAllocator w/o port expiration.
+ self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, 0)
+
+ # Ensure Get() succeeds and returns the correct port.
+ self.assertEquals(self._pa.Get('ip1', t=1), cns._DEFAULT_CNS_PORT_RANGE[0])
+ self.assertEquals(self._pa.Get('ip1', t=2),
+ cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+ self.assertEquals(self._pa.Get('ip1', t=3),
+ cns._DEFAULT_CNS_PORT_RANGE[0] + 2)
+ self.assertEquals(self._pa.Get('ip2', t=1),
+ cns._DEFAULT_CNS_PORT_RANGE[0] + 3)
+
+ self._pa.Cleanup(all_ports=False, request_ip='ip1')
+
+ self.assertEquals(self._pa._ports.keys(),
+ [cns._DEFAULT_CNS_PORT_RANGE[0] + 3])
+ self.assertEquals(self._pa.Get('ip2'), cns._DEFAULT_CNS_PORT_RANGE[0])
+ self.assertEquals(self._pa.Get('ip1'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
+
+ self._pa.Cleanup(all_ports=False, request_ip='ip2')
+ self.assertEquals(self._pa._ports.keys(),
+ [cns._DEFAULT_CNS_PORT_RANGE[0] + 1])
+
+ self._pa.Cleanup(all_ports=False, request_ip='abc')
+ self.assertEquals(self._pa._ports.keys(),
+ [cns._DEFAULT_CNS_PORT_RANGE[0] + 1])
+
+ self._pa.Cleanup(all_ports=False, request_ip='ip1')
+ self.assertEquals(self._pa._ports.keys(), [])
+
+
+class ConstrainedNetworkServerTest(unittest.TestCase):
+ """End to end tests for ConstrainedNetworkServer system.
+
+ These tests require root access and run the cherrypy server along with
+ tc/iptables commands.
+ """
+
+ # Amount of time to wait for the CNS to start up.
+ _SERVER_START_SLEEP_SECS = 1
+
+ # Sample data used to verify file serving.
+ _TEST_DATA = 'The quick brown fox jumps over the lazy dog'
+
+ # Server information.
+ _SERVER_URL = ('http://127.0.0.1:%d/ServeConstrained?' %
+ cns._DEFAULT_SERVING_PORT)
+
+ # Setting for latency testing.
+ _LATENCY_TEST_SECS = 1
+
+ def _StartServer(self):
+ """Starts the CNS, returns pid."""
+ cmd = ['python', 'cns.py', '--interface=%s' % _INTERFACE]
+ process = subprocess.Popen(cmd, stderr=subprocess.PIPE)
+
+ # Wait for server to startup.
+ line = True
+ while line:
+ line = process.stderr.readline()
+ if 'STARTED' in line:
+ return process.pid
+
+ self.fail('Failed to start CNS.')
+
+ def setUp(self):
+ # Start the CNS.
+ self._server_pid = self._StartServer()
+
+ # Create temp file for serving. Run after server start so if a failure
+ # during setUp() occurs we don't leave junk files around.
+ f, self._file = tempfile.mkstemp(dir=os.getcwd())
+ os.write(f, self._TEST_DATA)
+ os.close(f)
+
+ # Strip cwd off so we have a proper relative path.
+ self._relative_fn = self._file[len(os.getcwd()) + 1:]
+
+ def tearDown(self):
+ os.unlink(self._file)
+ os.kill(self._server_pid, signal.SIGTERM)
+
+ def testServerServesFiles(self):
+ now = time.time()
+
+ f = urllib2.urlopen('%sf=%s' % (self._SERVER_URL, self._relative_fn))
+
+ # Verify file data is served correctly.
+ self.assertEqual(self._TEST_DATA, f.read())
+
+ # For completeness ensure an unconstrained call takes less time than our
+ # artificial constraints checked in the tests below.
+ self.assertTrue(time.time() - now < self._LATENCY_TEST_SECS)
+
+ def testServerLatencyConstraint(self):
+ """Tests serving a file with a latency network constraint."""
+ # Abort if does not have root access.
+ self.assertEqual(os.geteuid(), 0, 'You need root access to run this test.')
+ now = time.time()
+
+ base_url = '%sf=%s' % (self._SERVER_URL, self._relative_fn)
+ url = '%s&latency=%d' % (base_url, self._LATENCY_TEST_SECS * 1000)
+ f = urllib2.urlopen(url)
+
+ # Verify file data is served correctly.
+ self.assertEqual(self._TEST_DATA, f.read())
+
+ # Verify the request took longer than the requested latency.
+ self.assertTrue(time.time() - now > self._LATENCY_TEST_SECS)
+
+ # Verify the server properly redirected the URL.
+ self.assertTrue(f.geturl().startswith(base_url.replace(
+ str(cns._DEFAULT_SERVING_PORT), str(cns._DEFAULT_CNS_PORT_RANGE[0]))))
+
+
+class ConstrainedNetworkServerUnitTests(unittest.TestCase):
+ """ConstrainedNetworkServer class unit tests."""
+
+ def testGetServerURL(self):
+ """Test server URL is correct when using Cherrypy port."""
+ cns_obj = cns.ConstrainedNetworkServer(self.DummyOptions(), None)
+
+ self.assertEqual(cns_obj._GetServerURL('ab/xz.webm', port=1234, t=1),
+ 'http://127.0.0.1:1234/ServeConstrained?f=ab/xz.webm&t=1')
+
+ def testGetServerURLWithLocalServer(self):
+ """Test server URL is correct when using --local-server-port port."""
+ cns_obj = cns.ConstrainedNetworkServer(self.DummyOptionsWithServer(), None)
+
+ self.assertEqual(cns_obj._GetServerURL('ab/xz.webm', port=1234, t=1),
+ 'http://127.0.0.1:1234/media/ab/xz.webm?t=1')
+
+ class DummyOptions(object):
+ www_root = 'media'
+ port = 9000
+ cherrypy.url = lambda: 'http://127.0.0.1:9000/ServeConstrained'
+ local_server_port = None
+
+ class DummyOptionsWithServer(object):
+ www_root = 'media'
+ port = 9000
+ cherrypy.url = lambda: 'http://127.0.0.1:9000/ServeConstrained'
+ local_server_port = 8080
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/constrained_network_server/traffic_control.py b/chromium/media/tools/constrained_network_server/traffic_control.py
new file mode 100644
index 00000000000..e94cc8dc9ba
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/traffic_control.py
@@ -0,0 +1,354 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Traffic control library for constraining the network configuration on a port.
+
+The traffic controller sets up a constrained network configuration on a port.
+Traffic to the constrained port is forwarded to a specified server port.
+"""
+
+import logging
+import os
+import re
+import subprocess
+
+# The maximum bandwidth limit.
+_DEFAULT_MAX_BANDWIDTH_KBIT = 1000000
+
+
+class TrafficControlError(BaseException):
+ """Exception raised for errors in traffic control library.
+
+ Attributes:
+ msg: User defined error message.
+ cmd: Command for which the exception was raised.
+ returncode: Return code of running the command.
+ stdout: Output of running the command.
+ stderr: Error output of running the command.
+ """
+
+ def __init__(self, msg, cmd=None, returncode=None, output=None,
+ error=None):
+ BaseException.__init__(self, msg)
+ self.msg = msg
+ self.cmd = cmd
+ self.returncode = returncode
+ self.output = output
+ self.error = error
+
+
+def CheckRequirements():
+ """Checks if permissions are available to run traffic control commands.
+
+ Raises:
+ TrafficControlError: If permissions to run traffic control commands are not
+ available.
+ """
+ if os.geteuid() != 0:
+ _Exec(['sudo', '-n', 'tc', '-help'],
+ msg=('Cannot run \'tc\' command. Traffic Control must be run as root '
+ 'or have password-less sudo access to this command.'))
+ _Exec(['sudo', '-n', 'iptables', '-help'],
+ msg=('Cannot run \'iptables\' command. Traffic Control must be run '
+ 'as root or have password-less sudo access to this command.'))
+
+
+def CreateConstrainedPort(config):
+ """Creates a new constrained port.
+
+ Imposes packet level constraints such as bandwidth, latency, and packet loss
+ on a given port using the specified configuration dictionary. Traffic to that
+ port is forwarded to a specified server port.
+
+ Args:
+ config: Constraint configuration dictionary, format:
+ port: Port to constrain (integer 1-65535).
+ server_port: Port to redirect traffic on [port] to (integer 1-65535).
+ interface: Network interface name (string).
+ latency: Delay added on each packet sent (integer in ms).
+ bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
+ loss: Percentage of packets to drop (integer 0-100).
+
+ Raises:
+ TrafficControlError: If any operation fails. The message in the exception
+ describes what failed.
+ """
+ _CheckArgsExist(config, 'interface', 'port', 'server_port')
+ _AddRootQdisc(config['interface'])
+
+ try:
+ _ConfigureClass('add', config)
+ _AddSubQdisc(config)
+ _AddFilter(config['interface'], config['port'])
+ _AddIptableRule(config['interface'], config['port'], config['server_port'])
+ except TrafficControlError as e:
+ logging.debug('Error creating constrained port %d.\nError: %s\n'
+ 'Deleting constrained port.', config['port'], e.error)
+ DeleteConstrainedPort(config)
+ raise e
+
+
+def DeleteConstrainedPort(config):
+ """Deletes an existing constrained port.
+
+ Deletes constraints set on a given port and the traffic forwarding rule from
+ the constrained port to a specified server port.
+
+ The original constrained network configuration used to create the constrained
+ port must be passed in.
+
+ Args:
+ config: Constraint configuration dictionary, format:
+ port: Port to constrain (integer 1-65535).
+ server_port: Port to redirect traffic on [port] to (integer 1-65535).
+ interface: Network interface name (string).
+ bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
+
+ Raises:
+ TrafficControlError: If any operation fails. The message in the exception
+ describes what failed.
+ """
+ _CheckArgsExist(config, 'interface', 'port', 'server_port')
+ try:
+ # Delete filters first so it frees the class.
+ _DeleteFilter(config['interface'], config['port'])
+ finally:
+ try:
+ # Deleting the class deletes attached qdisc as well.
+ _ConfigureClass('del', config)
+ finally:
+ _DeleteIptableRule(config['interface'], config['port'],
+ config['server_port'])
+
+
+def TearDown(config):
+ """Deletes the root qdisc and all iptables rules.
+
+ Args:
+ config: Constraint configuration dictionary, format:
+ interface: Network interface name (string).
+
+ Raises:
+ TrafficControlError: If any operation fails. The message in the exception
+ describes what failed.
+ """
+ _CheckArgsExist(config, 'interface')
+
+ command = ['sudo', 'tc', 'qdisc', 'del', 'dev', config['interface'], 'root']
+ try:
+ _Exec(command, msg='Could not delete root qdisc.')
+ finally:
+ _DeleteAllIpTableRules()
+
+
+def _CheckArgsExist(config, *args):
+ """Check that the args exist in config dictionary and are not None.
+
+ Args:
+ config: Any dictionary.
+ *args: The list of key names to check.
+
+ Raises:
+ TrafficControlError: If any key name does not exist in config or is None.
+ """
+ for key in args:
+ if key not in config.keys() or config[key] is None:
+ raise TrafficControlError('Missing "%s" parameter.' % key)
+
+
+def _AddRootQdisc(interface):
+ """Sets up the default root qdisc.
+
+ Args:
+ interface: Network interface name.
+
+ Raises:
+ TrafficControlError: If adding the root qdisc fails for a reason other than
+ it already exists.
+ """
+ command = ['sudo', 'tc', 'qdisc', 'add', 'dev', interface, 'root', 'handle',
+ '1:', 'htb']
+ try:
+ _Exec(command, msg=('Error creating root qdisc. '
+ 'Make sure you have root access'))
+ except TrafficControlError as e:
+ # Ignore the error if root already exists.
+ if not 'File exists' in e.error:
+ raise e
+
+
+def _ConfigureClass(option, config):
+ """Adds or deletes a class and qdisc attached to the root.
+
+ The class specifies bandwidth, and qdisc specifies delay and packet loss. The
+ class ID is based on the config port.
+
+ Args:
+ option: Adds or deletes a class option [add|del].
+ config: Constraint configuration dictionary, format:
+ port: Port to constrain (integer 1-65535).
+ interface: Network interface name (string).
+ bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
+ """
+ # Use constrained port as class ID so we can attach the qdisc and filter to
+ # it, as well as delete the class, using only the port number.
+ class_id = '1:%x' % config['port']
+ if 'bandwidth' not in config.keys() or not config['bandwidth']:
+ bandwidth = _DEFAULT_MAX_BANDWIDTH_KBIT
+ else:
+ bandwidth = config['bandwidth']
+
+ bandwidth = '%dkbit' % bandwidth
+ command = ['sudo', 'tc', 'class', option, 'dev', config['interface'],
+ 'parent', '1:', 'classid', class_id, 'htb', 'rate', bandwidth,
+ 'ceil', bandwidth]
+ _Exec(command, msg=('Error configuring class ID %s using "%s" command.' %
+ (class_id, option)))
+
+
+def _AddSubQdisc(config):
+ """Adds a qdisc attached to the class identified by the config port.
+
+ Args:
+ config: Constraint configuration dictionary, format:
+ port: Port to constrain (integer 1-65535).
+ interface: Network interface name (string).
+ latency: Delay added on each packet sent (integer in ms).
+ loss: Percentage of packets to drop (integer 0-100).
+ """
+ port_hex = '%x' % config['port']
+ class_id = '1:%x' % config['port']
+ command = ['sudo', 'tc', 'qdisc', 'add', 'dev', config['interface'], 'parent',
+ class_id, 'handle', port_hex + ':0', 'netem']
+
+ # Check if packet-loss is set in the configuration.
+ if 'loss' in config.keys() and config['loss']:
+ loss = '%d%%' % config['loss']
+ command.extend(['loss', loss])
+ # Check if latency is set in the configuration.
+ if 'latency' in config.keys() and config['latency']:
+ latency = '%dms' % config['latency']
+ command.extend(['delay', latency])
+
+ _Exec(command, msg='Could not attach qdisc to class ID %s.' % class_id)
+
+
+def _AddFilter(interface, port):
+ """Redirects packets coming to a specified port into the constrained class.
+
+ Args:
+ interface: Interface name to attach the filter to (string).
+ port: Port number to filter packets with (integer 1-65535).
+ """
+ class_id = '1:%x' % port
+
+ command = ['sudo', 'tc', 'filter', 'add', 'dev', interface, 'protocol', 'ip',
+ 'parent', '1:', 'prio', '1', 'u32', 'match', 'ip', 'sport', port,
+ '0xffff', 'flowid', class_id]
+ _Exec(command, msg='Error adding filter on port %d.' % port)
+
+
+def _DeleteFilter(interface, port):
+ """Deletes the filter attached to the configured port.
+
+ Args:
+ interface: Interface name the filter is attached to (string).
+ port: Port number being filtered (integer 1-65535).
+ """
+ handle_id = _GetFilterHandleId(interface, port)
+ command = ['sudo', 'tc', 'filter', 'del', 'dev', interface, 'protocol', 'ip',
+ 'parent', '1:0', 'handle', handle_id, 'prio', '1', 'u32']
+ _Exec(command, msg='Error deleting filter on port %d.' % port)
+
+
+def _GetFilterHandleId(interface, port):
+ """Searches for the handle ID of the filter identified by the config port.
+
+ Args:
+ interface: Interface name the filter is attached to (string).
+ port: Port number being filtered (integer 1-65535).
+
+ Returns:
+ The handle ID.
+
+ Raises:
+ TrafficControlError: If handle ID was not found.
+ """
+ command = ['sudo', 'tc', 'filter', 'list', 'dev', interface, 'parent', '1:']
+ output = _Exec(command, msg='Error listing filters.')
+ # Search for the filter handle ID associated with class ID '1:port'.
+ handle_id_re = re.search(
+ '([0-9a-fA-F]{3}::[0-9a-fA-F]{3}).*(?=flowid 1:%x\s)' % port, output)
+ if handle_id_re:
+ return handle_id_re.group(1)
+ raise TrafficControlError(('Could not find filter handle ID for class ID '
+ '1:%x.') % port)
+
+
+def _AddIptableRule(interface, port, server_port):
+ """Forwards traffic from constrained port to a specified server port.
+
+ Args:
+ interface: Interface name to attach the filter to (string).
+ port: Port of incoming packets (integer 1-65535).
+ server_port: Server port to forward the packets to (integer 1-65535).
+ """
+ # Preroute rules for accessing the port through external connections.
+ command = ['sudo', 'iptables', '-t', 'nat', '-A', 'PREROUTING', '-i',
+ interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT',
+ '--to-port', server_port]
+ _Exec(command, msg='Error adding iptables rule for port %d.' % port)
+
+ # Output rules for accessing the rule through localhost or 127.0.0.1
+ command = ['sudo', 'iptables', '-t', 'nat', '-A', 'OUTPUT', '-p', 'tcp',
+ '--dport', port, '-j', 'REDIRECT', '--to-port', server_port]
+ _Exec(command, msg='Error adding iptables rule for port %d.' % port)
+
+
+def _DeleteIptableRule(interface, port, server_port):
+ """Deletes the iptable rule associated with specified port number.
+
+ Args:
+ interface: Interface name to attach the filter to (string).
+ port: Port of incoming packets (integer 1-65535).
+ server_port: Server port packets are forwarded to (integer 1-65535).
+ """
+ command = ['sudo', 'iptables', '-t', 'nat', '-D', 'PREROUTING', '-i',
+ interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT',
+ '--to-port', server_port]
+ _Exec(command, msg='Error deleting iptables rule for port %d.' % port)
+
+ command = ['sudo', 'iptables', '-t', 'nat', '-D', 'OUTPUT', '-p', 'tcp',
+ '--dport', port, '-j', 'REDIRECT', '--to-port', server_port]
+ _Exec(command, msg='Error adding iptables rule for port %d.' % port)
+
+
+def _DeleteAllIpTableRules():
+ """Deletes all iptables rules."""
+ command = ['sudo', 'iptables', '-t', 'nat', '-F']
+ _Exec(command, msg='Error deleting all iptables rules.')
+
+
+def _Exec(command, msg=None):
+ """Executes a command.
+
+ Args:
+ command: Command list to execute.
+ msg: Message describing the error in case the command fails.
+
+ Returns:
+ The standard output from running the command.
+
+ Raises:
+ TrafficControlError: If command fails. Message is set by the msg parameter.
+ """
+ cmd_list = [str(x) for x in command]
+ cmd = ' '.join(cmd_list)
+ logging.debug('Running command: %s', cmd)
+
+ p = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ output, error = p.communicate()
+ if p.returncode != 0:
+ raise TrafficControlError(msg, cmd, p.returncode, output, error)
+ return output.strip()
diff --git a/chromium/media/tools/constrained_network_server/traffic_control_test.py b/chromium/media/tools/constrained_network_server/traffic_control_test.py
new file mode 100755
index 00000000000..d6412533235
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/traffic_control_test.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""End-to-end tests for traffic control library."""
+import os
+import re
+import sys
+import unittest
+
+import traffic_control
+
+
+class TrafficControlTests(unittest.TestCase):
+ """System tests for traffic_control functions.
+
+ These tests require root access.
+ """
+ # A dummy interface name to use instead of real interface.
+ _INTERFACE = 'myeth'
+
+ def setUp(self):
+ """Setup a dummy interface."""
+ # If we update to python version 2.7 or newer we can use setUpClass() or
+ # unittest.skipIf().
+ if os.getuid() != 0:
+ sys.exit('You need root access to run these tests.')
+
+ command = ['ip', 'link', 'add', 'name', self._INTERFACE, 'type', 'dummy']
+ traffic_control._Exec(command, 'Error creating dummy interface %s.' %
+ self._INTERFACE)
+
+ def tearDown(self):
+ """Teardown the dummy interface and any network constraints on it."""
+ # Deleting the dummy interface deletes all associated constraints.
+ command = ['ip', 'link', 'del', self._INTERFACE]
+ traffic_control._Exec(command)
+
+ def testExecOutput(self):
+ output = traffic_control._Exec(['echo', ' Test '])
+ self.assertEqual(output, 'Test')
+
+ def testExecException(self):
+ self.assertRaises(traffic_control.TrafficControlError,
+ traffic_control._Exec, command=['ls', '!doesntExist!'])
+
+ def testExecErrorCustomMsg(self):
+ try:
+ traffic_control._Exec(['ls', '!doesntExist!'], msg='test_msg')
+ self.fail('No exception raised for invalid command.')
+ except traffic_control.TrafficControlError as e:
+ self.assertEqual(e.msg, 'test_msg')
+
+ def testAddRootQdisc(self):
+ """Checks adding a root qdisc is successful."""
+ config = {'interface': self._INTERFACE}
+ root_detail = 'qdisc htb 1: root'
+ # Assert no htb root at startup.
+ command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ self.assertFalse(root_detail in output)
+
+ traffic_control._AddRootQdisc(config['interface'])
+ output = traffic_control._Exec(command)
+ # Assert htb root is added.
+ self.assertTrue(root_detail in output)
+
+ def testConfigureClassAdd(self):
+ """Checks adding and deleting a class to the root qdisc."""
+ config = {
+ 'interface': self._INTERFACE,
+ 'port': 12345,
+ 'server_port': 33333,
+ 'bandwidth': 2000
+ }
+ class_detail = ('class htb 1:%x root prio 0 rate %dKbit ceil %dKbit' %
+ (config['port'], config['bandwidth'], config['bandwidth']))
+
+ # Add root qdisc.
+ traffic_control._AddRootQdisc(config['interface'])
+
+ # Assert class does not exist prior to adding it.
+ command = ['tc', 'class', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ self.assertFalse(class_detail in output)
+
+ # Add class to root.
+ traffic_control._ConfigureClass('add', config)
+
+ # Assert class is added.
+ command = ['tc', 'class', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ self.assertTrue(class_detail in output)
+
+ # Delete class.
+ traffic_control._ConfigureClass('del', config)
+
+ # Assert class is deleted.
+ command = ['tc', 'class', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ self.assertFalse(class_detail in output)
+
+ def testAddSubQdisc(self):
+ """Checks adding a sub qdisc to existing class."""
+ config = {
+ 'interface': self._INTERFACE,
+ 'port': 12345,
+ 'server_port': 33333,
+ 'bandwidth': 2000,
+ 'latency': 250,
+ 'loss': 5
+ }
+ qdisc_re_detail = ('qdisc netem %x: parent 1:%x .* delay %d.0ms loss %d%%' %
+ (config['port'], config['port'], config['latency'],
+ config['loss']))
+ # Add root qdisc.
+ traffic_control._AddRootQdisc(config['interface'])
+
+ # Add class to root.
+ traffic_control._ConfigureClass('add', config)
+
+ # Assert qdisc does not exist prior to adding it.
+ command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ handle_id_re = re.search(qdisc_re_detail, output)
+ self.assertEqual(handle_id_re, None)
+
+ # Add qdisc to class.
+ traffic_control._AddSubQdisc(config)
+
+ # Assert qdisc is added.
+ command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
+ output = traffic_control._Exec(command)
+ handle_id_re = re.search(qdisc_re_detail, output)
+ self.assertNotEqual(handle_id_re, None)
+
+ def testAddDeleteFilter(self):
+ config = {
+ 'interface': self._INTERFACE,
+ 'port': 12345,
+ 'bandwidth': 2000
+ }
+ # Assert no filter exists.
+ command = ['tc', 'filter', 'list', 'dev', config['interface'], 'parent',
+ '1:0']
+ output = traffic_control._Exec(command)
+ self.assertEqual(output, '')
+
+ # Create the root and class to which the filter will be attached.
+ # Add root qdisc.
+ traffic_control._AddRootQdisc(config['interface'])
+
+ # Add class to root.
+ traffic_control._ConfigureClass('add', config)
+
+ # Add the filter.
+ traffic_control._AddFilter(config['interface'], config['port'])
+ handle_id = traffic_control._GetFilterHandleId(config['interface'],
+ config['port'])
+ self.assertNotEqual(handle_id, None)
+
+ # Delete the filter.
+ # The output of tc filter list is not None because tc adds default filters.
+ traffic_control._DeleteFilter(config['interface'], config['port'])
+ self.assertRaises(traffic_control.TrafficControlError,
+ traffic_control._GetFilterHandleId, config['interface'],
+ config['port'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/constrained_network_server/traffic_control_unittest.py b/chromium/media/tools/constrained_network_server/traffic_control_unittest.py
new file mode 100755
index 00000000000..a6781e9dec2
--- /dev/null
+++ b/chromium/media/tools/constrained_network_server/traffic_control_unittest.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for traffic control library."""
+import unittest
+
+import traffic_control
+
+
+class TrafficControlUnitTests(unittest.TestCase):
+ """Unit tests for traffic control."""
+
+ # Stores commands called by the traffic control _Exec function.
+ commands = []
+
+ def _ExecMock(self, command, **kwargs):
+ """Mocks traffic_control._Exec and adds the command to commands list."""
+ cmd_list = [str(x) for x in command]
+ self.commands.append(' '.join(cmd_list))
+ return ''
+
+ def setUp(self):
+ """Resets the commands list and set the _Exec mock function."""
+ self.commands = []
+ self._old_Exec = traffic_control._Exec
+ traffic_control._Exec = self._ExecMock
+
+ def tearDown(self):
+ """Resets the _Exec mock function to the original."""
+ traffic_control._Exec = self._old_Exec
+
+ def testCreateConstrainedPort(self):
+ config = {
+ 'interface': 'fakeeth',
+ 'port': 12345,
+ 'server_port': 8888,
+ 'bandwidth': 256,
+ 'latency': 100,
+ 'loss': 2
+ }
+ traffic_control.CreateConstrainedPort(config)
+ expected = [
+ 'sudo tc qdisc add dev fakeeth root handle 1: htb',
+ 'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate '
+ '256kbit ceil 256kbit',
+ 'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem loss '
+ '2% delay 100ms',
+ 'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 match '
+ 'ip sport 12345 0xffff flowid 1:3039',
+ 'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j '
+ 'REDIRECT --to-port 8888',
+ 'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT '
+ '--to-port 8888'
+ ]
+ self.assertEqual(expected, self.commands)
+
+ def testCreateConstrainedPortDefaults(self):
+ config = {
+ 'interface': 'fakeeth',
+ 'port': 12345,
+ 'server_port': 8888,
+ 'latency': None
+ }
+ traffic_control.CreateConstrainedPort(config)
+ expected = [
+ 'sudo tc qdisc add dev fakeeth root handle 1: htb',
+ 'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate '
+ '%dkbit ceil %dkbit' % (traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT,
+ traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT),
+ 'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem',
+ 'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 '
+ 'match ip sport 12345 0xffff flowid 1:3039',
+ 'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j '
+ 'REDIRECT --to-port 8888',
+ 'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT '
+ '--to-port 8888'
+ ]
+ self.assertEqual(expected, self.commands)
+
+ def testDeleteConstrainedPort(self):
+ config = {
+ 'interface': 'fakeeth',
+ 'port': 12345,
+ 'server_port': 8888,
+ 'bandwidth': 256,
+ }
+ _old_GetFilterHandleId = traffic_control._GetFilterHandleId
+ traffic_control._GetFilterHandleId = lambda interface, port: '800::800'
+
+ try:
+ traffic_control.DeleteConstrainedPort(config)
+ expected = [
+ 'sudo tc filter del dev fakeeth protocol ip parent 1:0 handle '
+ '800::800 prio 1 u32',
+ 'sudo tc class del dev fakeeth parent 1: classid 1:3039 htb rate '
+ '256kbit ceil 256kbit',
+ 'sudo iptables -t nat -D PREROUTING -i fakeeth -p tcp --dport 12345 '
+ '-j REDIRECT --to-port 8888',
+ 'sudo iptables -t nat -D OUTPUT -p tcp --dport 12345 -j REDIRECT '
+ '--to-port 8888']
+ self.assertEqual(expected, self.commands)
+ finally:
+ traffic_control._GetFilterHandleId = _old_GetFilterHandleId
+
+ def testTearDown(self):
+ config = {'interface': 'fakeeth'}
+
+ traffic_control.TearDown(config)
+ expected = [
+ 'sudo tc qdisc del dev fakeeth root',
+ 'sudo iptables -t nat -F'
+ ]
+ self.assertEqual(expected, self.commands)
+
+ def testGetFilterHandleID(self):
+ # Check seach for handle ID command.
+ self.assertRaises(traffic_control.TrafficControlError,
+ traffic_control._GetFilterHandleId, 'fakeeth', 1)
+ self.assertEquals(self.commands, ['sudo tc filter list dev fakeeth parent '
+ '1:'])
+
+ # Check with handle ID available.
+ traffic_control._Exec = (lambda command, msg:
+ 'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht '
+ '800 bkt 0 flowid 1:1\nmatch 08ae0000/ffff0000 at 20')
+ output = traffic_control._GetFilterHandleId('fakeeth', 1)
+ self.assertEqual(output, '800::800')
+
+ # Check with handle ID not available.
+ traffic_control._Exec = (lambda command, msg:
+ 'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht '
+ '800 bkt 0 flowid 1:11\nmatch 08ae0000/ffff0000 at 20')
+ self.assertRaises(traffic_control.TrafficControlError,
+ traffic_control._GetFilterHandleId, 'fakeeth', 1)
+
+ traffic_control._Exec = lambda command, msg: 'NO ID IN HERE'
+ self.assertRaises(traffic_control.TrafficControlError,
+ traffic_control._GetFilterHandleId, 'fakeeth', 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/demuxer_bench/demuxer_bench.cc b/chromium/media/tools/demuxer_bench/demuxer_bench.cc
new file mode 100644
index 00000000000..d38e5877433
--- /dev/null
+++ b/chromium/media/tools/demuxer_bench/demuxer_bench.cc
@@ -0,0 +1,240 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// demuxer_bench is a standalone benchmarking tool for FFmpegDemuxer. It
+// simulates the reading requirements for playback by reading from the stream
+// that has the earliest timestamp.
+
+#include <iostream>
+
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "media/base/media.h"
+#include "media/base/media_log.h"
+#include "media/filters/ffmpeg_demuxer.h"
+#include "media/filters/file_data_source.h"
+
+namespace switches {
+const char kEnableBitstreamConverter[] = "enable-bitstream-converter";
+} // namespace switches
+
+class DemuxerHostImpl : public media::DemuxerHost {
+ public:
+ DemuxerHostImpl() {}
+ virtual ~DemuxerHostImpl() {}
+
+ // DataSourceHost implementation.
+ virtual void SetTotalBytes(int64 total_bytes) OVERRIDE {}
+ virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE {}
+ virtual void AddBufferedTimeRange(base::TimeDelta start,
+ base::TimeDelta end) OVERRIDE {}
+
+ // DemuxerHost implementation.
+ virtual void SetDuration(base::TimeDelta duration) OVERRIDE {}
+ virtual void OnDemuxerError(media::PipelineStatus error) OVERRIDE {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DemuxerHostImpl);
+};
+
+void QuitLoopWithStatus(base::MessageLoop* message_loop,
+ media::PipelineStatus status) {
+ CHECK_EQ(status, media::PIPELINE_OK);
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+}
+
+static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data,
+ int init_data_size) {
+ LOG(INFO) << "File is encrypted.";
+}
+
+typedef std::vector<media::DemuxerStream* > Streams;
+
+// Simulates playback reading requirements by reading from each stream
+// present in |demuxer| in as-close-to-monotonically-increasing timestamp order.
+class StreamReader {
+ public:
+ StreamReader(media::Demuxer* demuxer, bool enable_bitstream_converter);
+ ~StreamReader();
+
+ // Performs a single step read.
+ void Read();
+
+ // Returns true when all streams have reached end of stream.
+ bool IsDone();
+
+ int number_of_streams() { return streams_.size(); }
+ const Streams& streams() { return streams_; }
+ const std::vector<int>& counts() { return counts_; }
+
+ private:
+ void OnReadDone(base::MessageLoop* message_loop,
+ bool* end_of_stream,
+ base::TimeDelta* timestamp,
+ media::DemuxerStream::Status status,
+ const scoped_refptr<media::DecoderBuffer>& buffer);
+ int GetNextStreamIndexToRead();
+
+ Streams streams_;
+ std::vector<bool> end_of_stream_;
+ std::vector<base::TimeDelta> last_read_timestamp_;
+ std::vector<int> counts_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamReader);
+};
+
+StreamReader::StreamReader(media::Demuxer* demuxer,
+ bool enable_bitstream_converter) {
+ media::DemuxerStream* stream =
+ demuxer->GetStream(media::DemuxerStream::AUDIO);
+ if (stream) {
+ streams_.push_back(stream);
+ end_of_stream_.push_back(false);
+ last_read_timestamp_.push_back(media::kNoTimestamp());
+ counts_.push_back(0);
+ }
+
+ stream = demuxer->GetStream(media::DemuxerStream::VIDEO);
+ if (stream) {
+ streams_.push_back(stream);
+ end_of_stream_.push_back(false);
+ last_read_timestamp_.push_back(media::kNoTimestamp());
+ counts_.push_back(0);
+
+ if (enable_bitstream_converter)
+ stream->EnableBitstreamConverter();
+ }
+}
+
+StreamReader::~StreamReader() {}
+
+void StreamReader::Read() {
+ int index = GetNextStreamIndexToRead();
+ bool end_of_stream = false;
+ base::TimeDelta timestamp;
+
+ streams_[index]->Read(base::Bind(
+ &StreamReader::OnReadDone, base::Unretained(this),
+ base::MessageLoop::current(), &end_of_stream, &timestamp));
+ base::MessageLoop::current()->Run();
+
+ CHECK(end_of_stream || timestamp != media::kNoTimestamp());
+ end_of_stream_[index] = end_of_stream;
+ last_read_timestamp_[index] = timestamp;
+ counts_[index]++;
+}
+
+bool StreamReader::IsDone() {
+ for (size_t i = 0; i < end_of_stream_.size(); ++i) {
+ if (!end_of_stream_[i])
+ return false;
+ }
+ return true;
+}
+
+void StreamReader::OnReadDone(
+ base::MessageLoop* message_loop,
+ bool* end_of_stream,
+ base::TimeDelta* timestamp,
+ media::DemuxerStream::Status status,
+ const scoped_refptr<media::DecoderBuffer>& buffer) {
+ CHECK_EQ(status, media::DemuxerStream::kOk);
+ CHECK(buffer.get());
+ *end_of_stream = buffer->end_of_stream();
+ *timestamp = *end_of_stream ? media::kNoTimestamp() : buffer->timestamp();
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+}
+
+int StreamReader::GetNextStreamIndexToRead() {
+ int index = -1;
+ for (int i = 0; i < number_of_streams(); ++i) {
+ // Ignore streams at EOS.
+ if (end_of_stream_[i])
+ continue;
+
+ // Use a stream if it hasn't been read from yet.
+ if (last_read_timestamp_[i] == media::kNoTimestamp())
+ return i;
+
+ if (index < 0 ||
+ last_read_timestamp_[i] < last_read_timestamp_[index]) {
+ index = i;
+ }
+ }
+ CHECK_GE(index, 0) << "Couldn't find a stream to read";
+ return index;
+}
+
+int main(int argc, char** argv) {
+ base::AtExitManager at_exit;
+ media::InitializeMediaLibraryForTesting();
+
+ CommandLine::Init(argc, argv);
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+
+ if (cmd_line->GetArgs().empty()) {
+ std::cerr << "Usage: " << argv[0] << " [file]\n\n"
+ << "Options:\n"
+ << " --" << switches::kEnableBitstreamConverter
+ << " Enables H.264 Annex B bitstream conversion"
+ << std::endl;
+ return 1;
+ }
+
+ base::MessageLoop message_loop;
+ DemuxerHostImpl demuxer_host;
+ base::FilePath file_path(cmd_line->GetArgs()[0]);
+
+ // Setup.
+ media::FileDataSource data_source;
+ CHECK(data_source.Initialize(file_path));
+
+ media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
+ media::FFmpegDemuxer demuxer(message_loop.message_loop_proxy(),
+ &data_source,
+ need_key_cb,
+ new media::MediaLog());
+
+ demuxer.Initialize(&demuxer_host, base::Bind(
+ &QuitLoopWithStatus, &message_loop));
+ message_loop.Run();
+
+ StreamReader stream_reader(
+ &demuxer, cmd_line->HasSwitch(switches::kEnableBitstreamConverter));
+
+ // Benchmark.
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ while (!stream_reader.IsDone()) {
+ stream_reader.Read();
+ }
+ base::TimeTicks end = base::TimeTicks::HighResNow();
+
+ // Results.
+ std::cout << "Time: " << (end - start).InMillisecondsF() << " ms\n";
+ for (int i = 0; i < stream_reader.number_of_streams(); ++i) {
+ media::DemuxerStream* stream = stream_reader.streams()[i];
+ std::cout << "Stream #" << i << ": ";
+
+ if (stream->type() == media::DemuxerStream::AUDIO) {
+ std::cout << "audio";
+ } else if (stream->type() == media::DemuxerStream::VIDEO) {
+ std::cout << "video";
+ } else {
+ std::cout << "unknown";
+ }
+
+ std::cout << ", " << stream_reader.counts()[i] << " packets" << std::endl;
+ }
+
+ // Teardown.
+ demuxer.Stop(base::Bind(
+ &QuitLoopWithStatus, &message_loop, media::PIPELINE_OK));
+ message_loop.Run();
+
+ return 0;
+}
diff --git a/chromium/media/tools/layout_tests/README b/chromium/media/tools/layout_tests/README
new file mode 100644
index 00000000000..37bc77d5261
--- /dev/null
+++ b/chromium/media/tools/layout_tests/README
@@ -0,0 +1,93 @@
+Layout test analyzer script.
+
+* Prerequisite:
+
+This script requires PySVN (http://pysvn.tigris.org/) to be installed on the
+machine.
+
+* How to execute
+
+python layouttest_analyzer.py (Please run with '-h' for available command-line
+ options)
+
+Example: python layouttest_analyzer.py -r imasaki@chromium.org
+-t /var/www/analyzer/graph.html
+
+* File/Directory structure
+
+layout_tests/
+ README: this file.
+ *.py: python scripts.
+ tmp/: temp files.
+ test_data/: data for unit tests.
+ graph/: the default location for graph files.
+ anno/: the default location for bug annotation files.
+ result/: the default location for the analyzer results.
+ testname/: the default location for the test group definition files in CSV.
+
+* Execution overview.
+
+1) using PySVN, the script collects layout test of interest
+(specified in command-line parameter and testnames/*.csv file) from
+Webkit SVN repository as well as test description. Then, it gets the
+latest test expectation file and does the simple parsing. The
+parsed test expectation is joined with the layout tests using test name
+as its join key. The tests are classified into 'whole', 'skip',
+'nonskip' test groups. 'Whole' contains all tests, 'skip' contains
+tests that are skipped as specified in the test expectation file, 'nonskip'
+tests are in the test expectation file and not skipped (these are tests
+that need attention).
+
+2) the script reads the previous latest analyzer results, then,
+compares it with current results for each test group ('whole', 'skip',
+and 'nonskip'). It also looks into the SVN test expectation history
+diff for the time period for the test names of interest.
+
+3) all obtained information is sent out to a email list specified
+in the parameters in pretty HTML format.
+
+4) the trend graph is updated using the current results.
+
+* Components
+
+** LayoutTests:
+
+A class to store test names in layout tests. The test names (including
+regular expression patterns) are read from a CSV file and used for
+getting layout test names from Webkit SVN as well as test description.
+
+** TestExpectations:
+
+A class to model the content of test expectation file for analysis.
+The location of the test expectations file can be found in
+|TEST_EXPECTATIONS_LOCATIONS|. It is necessary to parse this
+file and store meaningful information for the analysis (joining with
+existing layout tests using a test name). Instance variable
+|all_test_expectation_info| is used. A test name such as
+'media/video-source-type.html' is used for the key to store
+information. However, a test name can appear multiple times in the
+test expectation file. So, the map should keep all the occurrence
+information. For example, the current test expectation file has the
+following two entries:
+
+BUGWK58587 LINUX DEBUG GPU : media/video-zoom.html = IMAGE
+BUGCR86714 MAC GPU : media/video-zoom.html = CRASH IMAGE
+
+In this case, all_test_expectation_info['media/video-zoom.html'] will
+have a list with two elements, each of which is the map of the test
+expectation information.
+
+** TestExpectationsHistory:
+
+A class to represent history of the test expectation file. The history
+is obtained by calling PySVN.log()/diff() APIs using the specified time
+period.
+
+** TrendGraph:
+
+A class to manage trend graph which is using Google Visualization
+ APIs. Google Visualization API
+ (http://code.google.com/apis/chart/interactive/docs/gallery/annotatedtimeline.html)
+ is used to present the historical analyzer result. Currently, data
+ is directly written to JavaScript file using file in-place
+ replacement for simplicity.
diff --git a/chromium/media/tools/layout_tests/bug.py b/chromium/media/tools/layout_tests/bug.py
new file mode 100644
index 00000000000..d8cd20a1b3f
--- /dev/null
+++ b/chromium/media/tools/layout_tests/bug.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Bug module that is necessary for the layout analyzer."""
+
+import re
+
+from webkitpy.layout_tests.models.test_expectations import *
+
+
+class Bug(object):
+ """A class representing a bug.
+
+ TODO(imasaki): add more functionalities here if bug-tracker API is available.
+ For example, you can get the name of a bug owner.
+ """
+ # Type enum for the bug.
+ WEBKIT = 0
+ CHROMIUM = 1
+ OTHERS = 2
+
+ def __init__(self, bug_modifier):
+ """Initialize the object using raw bug text (such as BUGWK2322).
+
+ The bug modifier used in the test expectation file.
+
+ Args:
+ bug_modifier: a string representing a bug modifier. According to
+ http://www.chromium.org/developers/testing/webkit-layout-tests/\
+ testexpectations
+ Bug identifiers are of the form "webkit.org/b/12345", "crbug.com/12345",
+ "code.google.com/p/v8/issues/detail?id=12345" or "Bug(username)"
+ """
+ match = re.match('Bug\((\w+)\)$', bug_modifier)
+ if match:
+ self.type = self.OTHERS
+ self.url = 'mailto:%s@chromium.org' % match.group(1).lower()
+ self.bug_txt = bug_modifier
+ return
+
+ self.type = self.GetBugType(bug_modifier)
+ self.url = bug_modifier
+ self.bug_txt = bug_modifier
+
+
+ def GetBugType(self, bug_modifier):
+ """Returns type of the bug based on URL."""
+ if bug_modifier.startswith(WEBKIT_BUG_PREFIX):
+ return self.WEBKIT;
+ if bug_modifier.startswith(CHROMIUM_BUG_PREFIX):
+ return self.CHROMIUM;
+ return self.OTHERS
+
+ def __str__(self):
+ """Get a string representation of a bug object.
+
+ Returns:
+ a string for HTML link representation of a bug.
+ """
+ return '<a href="%s">%s</a>' % (self.url, self.bug_txt)
diff --git a/chromium/media/tools/layout_tests/graph/graph.html b/chromium/media/tools/layout_tests/graph/graph.html
new file mode 100644
index 00000000000..a54aa4dccd1
--- /dev/null
+++ b/chromium/media/tools/layout_tests/graph/graph.html
@@ -0,0 +1,53 @@
+<html>
+ <head>
+ <script type='text/javascript' src='https://www.google.com/jsapi'></script>
+ <script type='text/javascript'>
+ google.load('visualization', '1', {'packages': ['annotatedtimeline']});
+ google.setOnLoadCallback(drawChart);
+ function drawChart() {
+ var data = new google.visualization.DataTable();
+ data.addColumn('date', 'Date');
+ data.addColumn('number', '#Tests');
+ data.addColumn('string', 'title1');
+ data.addColumn('string', 'text1');
+ data.addColumn('number', '#Skipped tests');
+ data.addColumn('string', 'title2');
+ data.addColumn('string', 'text2');
+ data.addColumn('number', '#Non-skipped tests');
+ data.addColumn('string', 'title2');
+ data.addColumn('string', 'text2');
+ data.addRows([
+ // insert 1
+ ]);
+ var data2 = new google.visualization.DataTable();
+ data2.addColumn('date', 'Date');
+ data2.addColumn('number', 'Passing Rate ' +
+ '(100-(#Non-skipped tests)/' +
+ '((#Tests)-(#Skipped tests))*100)');
+ data2.addColumn('string', 'title1');
+ data2.addColumn('string', 'text1');
+ data2.addRows([
+ // insert 2
+ ]);
+ var div1 = document.getElementById('chart_div');
+ var chart = new google.visualization.AnnotatedTimeLine(div1);
+ chart.draw(data, {displayAnnotations: true, allowHtml: true});
+
+ var div2 = document.getElementById('chart_div2');
+ var chart2 = new google.visualization.AnnotatedTimeLine(div2);
+ chart2.draw(data2, {displayAnnotations: true,
+ allowHtml: true,
+ scaleType: 'maximized'});
+ }
+ </script>
+ <title>Media Layout Test Analyzer Result</title>
+ </head>
+
+ <body>
+ <h2>Current Statistics</h2>
+ <h3 id='numbers'>Numbers</h3>
+ <div id='chart_div' style='width: 1400px; height: 480px;'></div>
+ <h3>Test passing rate</h3>
+ <div id='chart_div2' style='width: 1400px; height: 480px;'></div>
+ </body>
+</html>
diff --git a/chromium/media/tools/layout_tests/layouttest_analyzer.py b/chromium/media/tools/layout_tests/layouttest_analyzer.py
new file mode 100755
index 00000000000..7459a977891
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttest_analyzer.py
@@ -0,0 +1,479 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Main functions for the Layout Test Analyzer module."""
+
+from datetime import datetime
+import optparse
+import os
+import sys
+import time
+
+import layouttest_analyzer_helpers
+from layouttest_analyzer_helpers import DEFAULT_REVISION_VIEW_URL
+import layouttests
+from layouttests import DEFAULT_LAYOUTTEST_SVN_VIEW_LOCATION
+
+from test_expectations import TestExpectations
+from trend_graph import TrendGraph
+
+# Predefined result directory.
+DEFAULT_RESULT_DIR = 'result'
+# TODO(shadi): Remove graph functions as they are not used any more.
+DEFAULT_GRAPH_FILE = os.path.join('graph', 'graph.html')
+# TODO(shadi): Check if these files are needed any more.
+DEFAULT_STATS_CSV_FILENAME = 'stats.csv'
+DEFAULT_ISSUES_CSV_FILENAME = 'issues.csv'
+# TODO(shadi): These are used only for |debug| mode. What is debug mode for?
+# AFAIK, we don't run debug mode, should be safe to remove.
+# Predefined result files for debug.
+CUR_TIME_FOR_DEBUG = '2011-09-11-19'
+CURRENT_RESULT_FILE_FOR_DEBUG = os.path.join(DEFAULT_RESULT_DIR,
+ CUR_TIME_FOR_DEBUG)
+PREV_TIME_FOR_DEBUG = '2011-09-11-18'
+
+# Text to append at the end of every analyzer result email.
+DEFAULT_EMAIL_APPEND_TEXT = (
+ '<b><a href="https://groups.google.com/a/google.com/group/'
+ 'layout-test-analyzer-result/topics">Email History</a></b><br>'
+ )
+
+
+def ParseOption():
+ """Parse command-line options using OptionParser.
+
+ Returns:
+ an object containing all command-line option information.
+ """
+ option_parser = optparse.OptionParser()
+
+ option_parser.add_option('-r', '--receiver-email-address',
+ dest='receiver_email_address',
+ help=('receiver\'s email address. '
+ 'Result email is not sent if this is not '
+ 'specified.'))
+ option_parser.add_option('-g', '--debug-mode', dest='debug',
+ help=('Debug mode is used when you want to debug '
+ 'the analyzer by using local file rather '
+ 'than getting data from SVN. This shortens '
+ 'the debugging time (off by default).'),
+ action='store_true', default=False)
+ option_parser.add_option('-t', '--trend-graph-location',
+ dest='trend_graph_location',
+ help=('Location of the bug trend file; '
+ 'file is expected to be in Google '
+ 'Visualization API trend-line format '
+ '(defaults to %default).'),
+ default=DEFAULT_GRAPH_FILE)
+ option_parser.add_option('-n', '--test-group-file-location',
+ dest='test_group_file_location',
+ help=('Location of the test group file; '
+ 'file is expected to be in CSV format '
+ 'and lists all test name patterns. '
+ 'When this option is not specified, '
+ 'the value of --test-group-name is used '
+ 'for a test name pattern.'),
+ default=None)
+ option_parser.add_option('-x', '--test-group-name',
+ dest='test_group_name',
+ help=('A name of test group. Either '
+ '--test_group_file_location or this option '
+ 'needs to be specified.'))
+ option_parser.add_option('-d', '--result-directory-location',
+ dest='result_directory_location',
+ help=('Name of result directory location '
+ '(default to %default).'),
+ default=DEFAULT_RESULT_DIR)
+ option_parser.add_option('-b', '--email-appended-text-file-location',
+ dest='email_appended_text_file_location',
+ help=('File location of the email appended text. '
+ 'The text is appended in the status email. '
+ '(default to %default and no text is '
+ 'appended in that case).'),
+ default=None)
+ option_parser.add_option('-c', '--email-only-change-mode',
+ dest='email_only_change_mode',
+ help=('With this mode, email is sent out '
+ 'only when there is a change in the '
+ 'analyzer result compared to the previous '
+ 'result (off by default)'),
+ action='store_true', default=False)
+ option_parser.add_option('-q', '--dashboard-file-location',
+ dest='dashboard_file_location',
+ help=('Location of dashboard file. The results are '
+ 'not reported to the dashboard if this '
+ 'option is not specified.'))
+ option_parser.add_option('-z', '--issue-detail-mode',
+ dest='issue_detail_mode',
+ help=('With this mode, email includes issue details '
+ '(links to the flakiness dashboard)'
+ ' (off by default)'),
+ action='store_true', default=False)
+ return option_parser.parse_args()[0]
+
+
+def GetCurrentAndPreviousResults(debug, test_group_file_location,
+ test_group_name, result_directory_location):
+ """Get current and the latest previous analyzer results.
+
+ In debug mode, they are read from predefined files. In non-debug mode,
+ current analyzer results are dynamically obtained from Blink SVN and
+ the latest previous result is read from the corresponding file.
+
+ Args:
+ debug: please refer to |options|.
+ test_group_file_location: please refer to |options|.
+ test_group_name: please refer to |options|.
+ result_directory_location: please refer to |options|.
+
+ Returns:
+ a tuple of the following:
+ prev_time: the previous time string that is compared against.
+ prev_analyzer_result_map: previous analyzer result map. Please refer to
+ layouttest_analyzer_helpers.AnalyzerResultMap.
+ analyzer_result_map: current analyzer result map. Please refer to
+ layouttest_analyzer_helpers.AnalyzerResultMap.
+ """
+ if not debug:
+ if not test_group_file_location and not test_group_name:
+ print ('Either --test-group-name or --test_group_file_location must be '
+ 'specified. Exiting this program.')
+ sys.exit()
+ filter_names = []
+ if test_group_file_location and os.path.exists(test_group_file_location):
+ filter_names = layouttests.LayoutTests.GetLayoutTestNamesFromCSV(
+ test_group_file_location)
+ parent_location_list = (
+ layouttests.LayoutTests.GetParentDirectoryList(filter_names))
+ recursion = True
+ else:
+ # When test group CSV file is not specified, test group name
+ # (e.g., 'media') is used for getting layout tests.
+ # The tests are in
+ # http://src.chromium.org/blink/trunk/LayoutTests/media
+ # Filtering is not set so all HTML files are considered as valid tests.
+ # Also, we look for the tests recursively.
+ if not test_group_file_location or (
+ not os.path.exists(test_group_file_location)):
+ print ('Warning: CSV file (%s) does not exist. So it is ignored and '
+ '%s is used for obtaining test names') % (
+ test_group_file_location, test_group_name)
+ if not test_group_name.endswith('/'):
+ test_group_name += '/'
+ parent_location_list = [test_group_name]
+ filter_names = None
+ recursion = True
+ layouttests_object = layouttests.LayoutTests(
+ parent_location_list=parent_location_list, recursion=recursion,
+ filter_names=filter_names)
+ analyzer_result_map = layouttest_analyzer_helpers.AnalyzerResultMap(
+ layouttests_object.JoinWithTestExpectation(TestExpectations()))
+ result = layouttest_analyzer_helpers.FindLatestResult(
+ result_directory_location)
+ if result:
+ (prev_time, prev_analyzer_result_map) = result
+ else:
+ prev_time = None
+ prev_analyzer_result_map = None
+ else:
+ analyzer_result_map = layouttest_analyzer_helpers.AnalyzerResultMap.Load(
+ CURRENT_RESULT_FILE_FOR_DEBUG)
+ prev_time = PREV_TIME_FOR_DEBUG
+ prev_analyzer_result_map = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(
+ os.path.join(DEFAULT_RESULT_DIR, prev_time)))
+ return (prev_time, prev_analyzer_result_map, analyzer_result_map)
+
+
+def SendEmail(prev_time, prev_analyzer_result_map, analyzer_result_map,
+ appended_text_to_email, email_only_change_mode, debug,
+ receiver_email_address, test_group_name, issue_detail_mode):
+ """Send result status email.
+
+ Args:
+ prev_time: the previous time string that is compared against.
+ prev_analyzer_result_map: previous analyzer result map. Please refer to
+ layouttest_analyzer_helpers.AnalyzerResultMap.
+ analyzer_result_map: current analyzer result map. Please refer to
+ layouttest_analyzer_helpers.AnalyzerResultMap.
+ appended_text_to_email: the text string to append to the status email.
+ email_only_change_mode: please refer to |options|.
+ debug: please refer to |options|.
+ receiver_email_address: please refer to |options|.
+ test_group_name: please refer to |options|.
+ issue_detail_mode: please refer to |options|.
+
+ Returns:
+ a tuple of the following:
+ result_change: a boolean indicating whether there is a change in the
+ result compared with the latest past result.
+ diff_map: please refer to
+ layouttest_analyzer_helpers.SendStatusEmail().
+ simple_rev_str: a simple version of revision string that is sent in
+ the email.
+ rev: the latest revision number for the given test group.
+ rev_date: the latest revision date for the given test group.
+ email_content: email content string (without
+ |appended_text_to_email|) that will be shown on the dashboard.
+ """
+ rev = ''
+ rev_date = ''
+ email_content = ''
+ if prev_analyzer_result_map:
+ diff_map = analyzer_result_map.CompareToOtherResultMap(
+ prev_analyzer_result_map)
+ result_change = (any(diff_map['whole']) or any(diff_map['skip']) or
+ any(diff_map['nonskip']))
+ # Email only when |email_only_change_mode| is False or there
+ # is a change in the result compared to the last result.
+ simple_rev_str = ''
+ if not email_only_change_mode or result_change:
+ prev_time_in_float = datetime.strptime(prev_time, '%Y-%m-%d-%H')
+ prev_time_in_float = time.mktime(prev_time_in_float.timetuple())
+ if debug:
+ cur_time_in_float = datetime.strptime(CUR_TIME_FOR_DEBUG,
+ '%Y-%m-%d-%H')
+ cur_time_in_float = time.mktime(cur_time_in_float.timetuple())
+ else:
+ cur_time_in_float = time.time()
+ (rev_str, simple_rev_str, rev, rev_date) = (
+ layouttest_analyzer_helpers.GetRevisionString(prev_time_in_float,
+ cur_time_in_float,
+ diff_map))
+ email_content = analyzer_result_map.ConvertToString(prev_time,
+ diff_map,
+ issue_detail_mode)
+ if receiver_email_address:
+ layouttest_analyzer_helpers.SendStatusEmail(
+ prev_time, analyzer_result_map, diff_map,
+ receiver_email_address, test_group_name,
+ appended_text_to_email, email_content, rev_str,
+ email_only_change_mode)
+ if simple_rev_str:
+ simple_rev_str = '\'' + simple_rev_str + '\''
+ else:
+ simple_rev_str = 'undefined' # GViz uses undefined for NONE.
+ else:
+ # Initial result should be written to tread-graph if there are no previous
+ # results.
+ result_change = True
+ diff_map = None
+ simple_rev_str = 'undefined'
+ email_content = analyzer_result_map.ConvertToString(None, diff_map,
+ issue_detail_mode)
+ return (result_change, diff_map, simple_rev_str, rev, rev_date,
+ email_content)
+
+
+def UpdateTrendGraph(start_time, analyzer_result_map, diff_map, simple_rev_str,
+ trend_graph_location):
+ """Update trend graph in GViz.
+
+ Annotate the graph with revision information.
+
+ Args:
+ start_time: the script starting time as a float value.
+ analyzer_result_map: current analyzer result map. Please refer to
+ layouttest_analyzer_helpers.AnalyzerResultMap.
+ diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys.
+ Please refer to |diff_map| in
+ |layouttest_analyzer_helpers.SendStatusEmail()|.
+ simple_rev_str: a simple version of revision string that is sent in
+ the email.
+ trend_graph_location: the location of the trend graph that needs to be
+ updated.
+
+ Returns:
+ a dictionary that maps result data category ('whole', 'skip', 'nonskip',
+ 'passingrate') to information tuple (a dictionary that maps test name
+ to its description, annotation, simple_rev_string) of the given result
+ data category. These tuples are used for trend graph update.
+ """
+ # Trend graph update (if specified in the command-line argument) when
+ # there is change from the last result.
+ # Currently, there are two graphs (graph1 is for 'whole', 'skip',
+ # 'nonskip' and the graph2 is for 'passingrate'). Please refer to
+ # graph/graph.html.
+ # Sample JS annotation for graph1:
+ # [new Date(2011,8,12,10,41,32),224,undefined,'',52,undefined,
+ # undefined, 12, 'test1,','<a href="http://t</a>,',],
+ # This example lists 'whole' triple and 'skip' triple and
+ # 'nonskip' triple. Each triple is (the number of tests that belong to
+ # the test group, linked text, a link). The following code generates this
+ # automatically based on rev_string etc.
+ trend_graph = TrendGraph(trend_graph_location)
+ datetime_string = start_time.strftime('%Y,%m,%d,%H,%M,%S')
+ data_map = {}
+ passingrate_anno = ''
+ for test_group in ['whole', 'skip', 'nonskip']:
+ anno = 'undefined'
+ # Extract test description.
+ test_map = {}
+ for (test_name, value) in (
+ analyzer_result_map.result_map[test_group].iteritems()):
+ test_map[test_name] = value['desc']
+ test_str = ''
+ links = ''
+ if diff_map and diff_map[test_group]:
+ for i in [0, 1]:
+ for (name, _) in diff_map[test_group][i]:
+ test_str += name + ','
+ # This is link to test HTML in SVN.
+ links += ('<a href="%s%s">%s</a>' %
+ (DEFAULT_LAYOUTTEST_SVN_VIEW_LOCATION, name, name))
+ if test_str:
+ anno = '\'' + test_str + '\''
+ # The annotation of passing rate is a union of all annotations.
+ passingrate_anno += anno
+ if links:
+ links = '\'' + links + '\''
+ else:
+ links = 'undefined'
+ if test_group is 'whole':
+ data_map[test_group] = (test_map, anno, links)
+ else:
+ data_map[test_group] = (test_map, anno, simple_rev_str)
+ if not passingrate_anno:
+ passingrate_anno = 'undefined'
+ data_map['passingrate'] = (
+ str(analyzer_result_map.GetPassingRate()), passingrate_anno,
+ simple_rev_str)
+ trend_graph.Update(datetime_string, data_map)
+ return data_map
+
+
+def UpdateDashboard(dashboard_file_location, test_group_name, data_map,
+ layouttest_root_path, rev, rev_date, email,
+ email_content):
+ """Update dashboard HTML file.
+
+ Args:
+ dashboard_file_location: the file location for the dashboard file.
+ test_group_name: please refer to |options|.
+ data_map: a dictionary that maps result data category ('whole', 'skip',
+ 'nonskip', 'passingrate') to information tuple (a dictionary that maps
+ test name to its description, annotation, simple_rev_string) of the
+ given result data category. These tuples are used for trend graph
+ update.
+ layouttest_root_path: A location string where layout tests are stored.
+ rev: the latest revision number for the given test group.
+ rev_date: the latest revision date for the given test group.
+ email: email address of the owner for the given test group.
+ email_content: email content string (without |appended_text_to_email|)
+ that will be shown on the dashboard.
+ """
+ # Generate a HTML file that contains all test names for each test group.
+ escaped_tg_name = test_group_name.replace('/', '_')
+ for tg in ['whole', 'skip', 'nonskip']:
+ file_name = os.path.join(
+ os.path.dirname(dashboard_file_location),
+ escaped_tg_name + '_' + tg + '.html')
+ file_object = open(file_name, 'wb')
+ file_object.write('<table border="1">')
+ sorted_testnames = data_map[tg][0].keys()
+ sorted_testnames.sort()
+ for testname in sorted_testnames:
+ file_object.write((
+ '<tr><td><a href="%s">%s</a></td><td><a href="%s">dashboard</a>'
+ '</td><td>%s</td></tr>') % (
+ layouttest_root_path + testname, testname,
+ ('http://test-results.appspot.com/dashboards/'
+ 'flakiness_dashboard.html#tests=%s') % testname,
+ data_map[tg][0][testname]))
+ file_object.write('</table>')
+ file_object.close()
+ email_content_with_link = ''
+ if email_content:
+ file_name = os.path.join(os.path.dirname(dashboard_file_location),
+ escaped_tg_name + '_email.html')
+ file_object = open(file_name, 'wb')
+ file_object.write(email_content)
+ file_object.close()
+ email_content_with_link = '<a href="%s_email.html">info</a>' % (
+ escaped_tg_name)
+ test_group_str = (
+ '<td><a href="%(test_group_path)s">%(test_group_name)s</a></td>'
+ '<td><a href="%(graph_path)s">graph</a></td>'
+ '<td><a href="%(all_tests_path)s">%(all_tests_count)d</a></td>'
+ '<td><a href="%(skip_tests_path)s">%(skip_tests_count)d</a></td>'
+ '<td><a href="%(nonskip_tests_path)s">%(nonskip_tests_count)d</a></td>'
+ '<td>%(fail_rate)d%%</td>'
+ '<td>%(passing_rate)d%%</td>'
+ '<td><a href="%(rev_url)s">%(rev)s</a></td>'
+ '<td>%(rev_date)s</td>'
+ '<td><a href="mailto:%(email)s">%(email)s</a></td>'
+ '<td>%(email_content)s</td>\n') % {
+ # Dashboard file and graph must be in the same directory
+ # to make the following link work.
+ 'test_group_path': layouttest_root_path + '/' + test_group_name,
+ 'test_group_name': test_group_name,
+ 'graph_path': escaped_tg_name + '.html',
+ 'all_tests_path': escaped_tg_name + '_whole.html',
+ 'all_tests_count': len(data_map['whole'][0]),
+ 'skip_tests_path': escaped_tg_name + '_skip.html',
+ 'skip_tests_count': len(data_map['skip'][0]),
+ 'nonskip_tests_path': escaped_tg_name + '_nonskip.html',
+ 'nonskip_tests_count': len(data_map['nonskip'][0]),
+ 'fail_rate': 100 - int(data_map['passingrate'][0]),
+ 'passing_rate': int(data_map['passingrate'][0]),
+ 'rev_url': DEFAULT_REVISION_VIEW_URL % rev,
+ 'rev': rev,
+ 'rev_date': rev_date,
+ 'email': email,
+ 'email_content': email_content_with_link
+ }
+ layouttest_analyzer_helpers.ReplaceLineInFile(
+ dashboard_file_location, '<td>' + test_group_name + '</td>',
+ test_group_str)
+
+
+def main():
+ """A main function for the analyzer."""
+ options = ParseOption()
+ start_time = datetime.now()
+
+ (prev_time, prev_analyzer_result_map, analyzer_result_map) = (
+ GetCurrentAndPreviousResults(options.debug,
+ options.test_group_file_location,
+ options.test_group_name,
+ options.result_directory_location))
+ (result_change, diff_map, simple_rev_str, rev, rev_date, email_content) = (
+ SendEmail(prev_time, prev_analyzer_result_map, analyzer_result_map,
+ DEFAULT_EMAIL_APPEND_TEXT,
+ options.email_only_change_mode, options.debug,
+ options.receiver_email_address, options.test_group_name,
+ options.issue_detail_mode))
+
+ # Create CSV texts and save them for bug spreadsheet.
+ (stats, issues_txt) = analyzer_result_map.ConvertToCSVText(
+ start_time.strftime('%Y-%m-%d-%H'))
+ file_object = open(os.path.join(options.result_directory_location,
+ DEFAULT_STATS_CSV_FILENAME), 'wb')
+ file_object.write(stats)
+ file_object.close()
+ file_object = open(os.path.join(options.result_directory_location,
+ DEFAULT_ISSUES_CSV_FILENAME), 'wb')
+ file_object.write(issues_txt)
+ file_object.close()
+
+ if not options.debug and (result_change or not prev_analyzer_result_map):
+ # Save the current result when result is changed or the script is
+ # executed for the first time.
+ date = start_time.strftime('%Y-%m-%d-%H')
+ file_path = os.path.join(options.result_directory_location, date)
+ analyzer_result_map.Save(file_path)
+ if result_change or not prev_analyzer_result_map:
+ data_map = UpdateTrendGraph(start_time, analyzer_result_map, diff_map,
+ simple_rev_str, options.trend_graph_location)
+ # Report the result to dashboard.
+ if options.dashboard_file_location:
+ UpdateDashboard(options.dashboard_file_location, options.test_group_name,
+ data_map, layouttests.DEFAULT_LAYOUTTEST_LOCATION, rev,
+ rev_date, options.receiver_email_address,
+ email_content)
+
+
+if '__main__' == __name__:
+ main()
diff --git a/chromium/media/tools/layout_tests/layouttest_analyzer_helpers.py b/chromium/media/tools/layout_tests/layouttest_analyzer_helpers.py
new file mode 100644
index 00000000000..2eb3c158789
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttest_analyzer_helpers.py
@@ -0,0 +1,596 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helper functions for the layout test analyzer."""
+
+from datetime import datetime
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+import fileinput
+import os
+import pickle
+import re
+import smtplib
+import socket
+import sys
+import time
+
+from bug import Bug
+from test_expectations_history import TestExpectationsHistory
+
+DEFAULT_TEST_EXPECTATION_PATH = ('trunk/LayoutTests/TestExpectations')
+LEGACY_DEFAULT_TEST_EXPECTATION_PATH = (
+ 'trunk/LayoutTests/platform/chromium/test_expectations.txt')
+REVISION_LOG_URL = ('http://build.chromium.org/f/chromium/perf/dashboard/ui/'
+ 'changelog_blink.html?url=/trunk/LayoutTests/%s&range=%d:%d')
+DEFAULT_REVISION_VIEW_URL = 'http://src.chromium.org/viewvc/blink?revision=%s'
+
+
+class AnalyzerResultMap:
+ """A class to deal with joined result produed by the analyzer.
+
+ The join is done between layouttests and the test_expectations object
+ (based on the test expectation file). The instance variable |result_map|
+ contains the following keys: 'whole','skip','nonskip'. The value of 'whole'
+ contains information about all layouttests. The value of 'skip' contains
+ information about skipped layouttests where it has 'SKIP' in its entry in
+ the test expectation file. The value of 'nonskip' contains all information
+ about non skipped layout tests, which are in the test expectation file but
+ not skipped. The information is exactly same as the one parsed by the
+ analyzer.
+ """
+
+ def __init__(self, test_info_map):
+ """Initialize the AnalyzerResultMap based on test_info_map.
+
+ Test_info_map contains all layouttest information. The job here is to
+ classify them as 'whole', 'skip' or 'nonskip' based on that information.
+
+ Args:
+ test_info_map: the result map of |layouttests.JoinWithTestExpectation|.
+ The key of the map is test name such as 'media/media-foo.html'.
+ The value of the map is a map that contains the following keys:
+ 'desc'(description), 'te_info' (test expectation information),
+ which is a list of test expectation information map. The key of the
+ test expectation information map is test expectation keywords such
+ as "SKIP" and other keywords (for full list of keywords, please
+ refer to |test_expectations.ALL_TE_KEYWORDS|).
+ """
+ self.result_map = {}
+ self.result_map['whole'] = {}
+ self.result_map['skip'] = {}
+ self.result_map['nonskip'] = {}
+ if test_info_map:
+ for (k, value) in test_info_map.iteritems():
+ self.result_map['whole'][k] = value
+ if 'te_info' in value:
+ # Don't count SLOW PASS, WONTFIX, or ANDROID tests as failures.
+ if any([True for x in value['te_info'] if set(x.keys()) ==
+ set(['SLOW', 'PASS', 'Bugs', 'Comments', 'Platforms']) or
+ 'WONTFIX' in x or x['Platforms'] == ['ANDROID']]):
+ continue
+ if any([True for x in value['te_info'] if 'SKIP' in x]):
+ self.result_map['skip'][k] = value
+ else:
+ self.result_map['nonskip'][k] = value
+
+ @staticmethod
+ def GetDiffString(diff_map_element, type_str):
+ """Get difference string out of diff map element.
+
+ The difference string shows difference between two analyzer results
+ (for example, a result for now and a result for sometime in the past)
+ in HTML format (with colors). This is used for generating email messages.
+
+ Args:
+ diff_map_element: An element of the compared map generated by
+ |CompareResultMaps()|. The element has two lists of test cases. One
+ is for test names that are in the current result but NOT in the
+ previous result. The other is for test names that are in the previous
+ results but NOT in the current result. Please refer to comments in
+ |CompareResultMaps()| for details.
+ type_str: a string indicating the test group to which |diff_map_element|
+ belongs; used for color determination. Must be 'whole', 'skip', or
+ 'nonskip'.
+
+ Returns:
+ a string in HTML format (with colors) to show difference between two
+ analyzer results.
+ """
+ if not diff_map_element[0] and not diff_map_element[1]:
+ return 'No Change'
+ color = ''
+ diff = len(diff_map_element[0]) - len(diff_map_element[1])
+ if diff > 0 and type_str != 'whole':
+ color = 'red'
+ else:
+ color = 'green'
+ diff_sign = ''
+ if diff > 0:
+ diff_sign = '+'
+ if not diff:
+ whole_str = 'No Change'
+ else:
+ whole_str = '<font color="%s">%s%d</font>' % (color, diff_sign, diff)
+ colors = ['red', 'green']
+ if type_str == 'whole':
+ # Bug 107773 - when we increase the number of tests,
+ # the name of the tests are in red, it should be green
+ # since it is good thing.
+ colors = ['green', 'red']
+ str1 = ''
+ for (name, _) in diff_map_element[0]:
+ str1 += '<font color="%s">%s,</font>' % (colors[0], name)
+ str2 = ''
+ for (name, _) in diff_map_element[1]:
+ str2 += '<font color="%s">%s,</font>' % (colors[1], name)
+ if str1 or str2:
+ whole_str += ':'
+ if str1:
+ whole_str += str1
+ if str2:
+ whole_str += str2
+ # Remove the last occurrence of ','.
+ whole_str = ''.join(whole_str.rsplit(',', 1))
+ return whole_str
+
+ def GetPassingRate(self):
+ """Get passing rate.
+
+ Returns:
+ layout test passing rate of this result in percent.
+
+ Raises:
+ ValueEror when the number of tests in test group "whole" is equal
+ or less than that of "skip".
+ """
+ delta = len(self.result_map['whole'].keys()) - (
+ len(self.result_map['skip'].keys()))
+ if delta <= 0:
+ raise ValueError('The number of tests in test group "whole" is equal or '
+ 'less than that of "skip"')
+ return 100 - len(self.result_map['nonskip'].keys()) * 100 / delta
+
+ def ConvertToCSVText(self, current_time):
+ """Convert |self.result_map| into stats and issues text in CSV format.
+
+ Both are used as inputs for Google spreadsheet.
+
+ Args:
+ current_time: a string depicting a time in year-month-day-hour
+ format (e.g., 2011-11-08-16).
+
+ Returns:
+ a tuple of stats and issues_txt
+ stats: analyzer result in CSV format that shows:
+ (current_time, the number of tests, the number of skipped tests,
+ the number of failing tests, passing rate)
+ For example,
+ "2011-11-10-15,204,22,12,94"
+ issues_txt: issues listed in CSV format that shows:
+ (BUGWK or BUGCR, bug number, the test expectation entry,
+ the name of the test)
+ For example,
+ "BUGWK,71543,TIMEOUT PASS,media/media-element-play-after-eos.html,
+ BUGCR,97657,IMAGE CPU MAC TIMEOUT PASS,media/audio-repaint.html,"
+ """
+ stats = ','.join([current_time, str(len(self.result_map['whole'].keys())),
+ str(len(self.result_map['skip'].keys())),
+ str(len(self.result_map['nonskip'].keys())),
+ str(self.GetPassingRate())])
+ issues_txt = ''
+ for bug_txt, test_info_list in (
+ self.GetListOfBugsForNonSkippedTests().iteritems()):
+ matches = re.match(r'(BUG(CR|WK))(\d+)', bug_txt)
+ bug_suffix = ''
+ bug_no = ''
+ if matches:
+ bug_suffix = matches.group(1)
+ bug_no = matches.group(3)
+ issues_txt += bug_suffix + ',' + bug_no + ','
+ for test_info in test_info_list:
+ test_name, te_info = test_info
+ issues_txt += ' '.join(te_info.keys()) + ',' + test_name + ','
+ issues_txt += '\n'
+ return stats, issues_txt
+
+ def ConvertToString(self, prev_time, diff_map, issue_detail_mode):
+ """Convert this result to HTML display for email.
+
+ Args:
+ prev_time: the previous time string that are compared against.
+ diff_map: the compared map generated by |CompareResultMaps()|.
+ issue_detail_mode: includes the issue details in the output string if
+ this is True.
+
+ Returns:
+ a analyzer result string in HTML format.
+ """
+ return_str = ''
+ if diff_map:
+ return_str += (
+ '<b>Statistics (Diff Compared to %s):</b><ul>'
+ '<li>The number of tests: %d (%s)</li>'
+ '<li>The number of failing skipped tests: %d (%s)</li>'
+ '<li>The number of failing non-skipped tests: %d (%s)</li>'
+ '<li>Passing rate: %d %%</li></ul>') % (
+ prev_time, len(self.result_map['whole'].keys()),
+ AnalyzerResultMap.GetDiffString(diff_map['whole'], 'whole'),
+ len(self.result_map['skip'].keys()),
+ AnalyzerResultMap.GetDiffString(diff_map['skip'], 'skip'),
+ len(self.result_map['nonskip'].keys()),
+ AnalyzerResultMap.GetDiffString(diff_map['nonskip'], 'nonskip'),
+ self.GetPassingRate())
+ if issue_detail_mode:
+ return_str += '<b>Current issues about failing non-skipped tests:</b>'
+ for (bug_txt, test_info_list) in (
+ self.GetListOfBugsForNonSkippedTests().iteritems()):
+ return_str += '<ul>%s' % Bug(bug_txt)
+ for test_info in test_info_list:
+ (test_name, te_info) = test_info
+ gpu_link = ''
+ if 'GPU' in te_info:
+ gpu_link = 'group=%40ToT%20GPU%20Mesa%20-%20chromium.org&'
+ dashboard_link = ('http://test-results.appspot.com/dashboards/'
+ 'flakiness_dashboard.html#%stests=%s') % (
+ gpu_link, test_name)
+ return_str += '<li><a href="%s">%s</a> (%s) </li>' % (
+ dashboard_link, test_name, ' '.join(
+ [key for key in te_info.keys() if key != 'Platforms']))
+ return_str += '</ul>\n'
+ return return_str
+
+ def CompareToOtherResultMap(self, other_result_map):
+ """Compare this result map with the other to see if there are any diff.
+
+ The comparison is done for layouttests which belong to 'whole', 'skip',
+ or 'nonskip'.
+
+ Args:
+ other_result_map: another result map to be compared against the result
+ map of the current object.
+
+ Returns:
+ a map that has 'whole', 'skip' and 'nonskip' as keys.
+ Please refer to |diff_map| in |SendStatusEmail()|.
+ """
+ comp_result_map = {}
+ for name in ['whole', 'skip', 'nonskip']:
+ if name == 'nonskip':
+ # Look into expectation to get diff only for non-skipped tests.
+ lookIntoTestExpectationInfo = True
+ else:
+ # Otherwise, only test names are compared to get diff.
+ lookIntoTestExpectationInfo = False
+ comp_result_map[name] = GetDiffBetweenMaps(
+ self.result_map[name], other_result_map.result_map[name],
+ lookIntoTestExpectationInfo)
+ return comp_result_map
+
+ @staticmethod
+ def Load(file_path):
+ """Load the object from |file_path| using pickle library.
+
+ Args:
+ file_path: the string path to the file from which to read the result.
+
+ Returns:
+ a AnalyzerResultMap object read from |file_path|.
+ """
+ file_object = open(file_path)
+ analyzer_result_map = pickle.load(file_object)
+ file_object.close()
+ return analyzer_result_map
+
+ def Save(self, file_path):
+ """Save the object to |file_path| using pickle library.
+
+ Args:
+ file_path: the string path to the file in which to store the result.
+ """
+ file_object = open(file_path, 'wb')
+ pickle.dump(self, file_object)
+ file_object.close()
+
+ def GetListOfBugsForNonSkippedTests(self):
+ """Get a list of bugs for non-skipped layout tests.
+
+ This is used for generating email content.
+
+ Returns:
+ a mapping from bug modifier text (e.g., BUGCR1111) to a test name and
+ main test information string which excludes comments and bugs.
+ This is used for grouping test names by bug.
+ """
+ bug_map = {}
+ for (name, value) in self.result_map['nonskip'].iteritems():
+ for te_info in value['te_info']:
+ main_te_info = {}
+ for k in te_info.keys():
+ if k != 'Comments' and k != 'Bugs':
+ main_te_info[k] = True
+ if 'Bugs' in te_info:
+ for bug in te_info['Bugs']:
+ if bug not in bug_map:
+ bug_map[bug] = []
+ bug_map[bug].append((name, main_te_info))
+ return bug_map
+
+
+def SendStatusEmail(prev_time, analyzer_result_map, diff_map,
+ receiver_email_address, test_group_name,
+ appended_text_to_email, email_content, rev_str,
+ email_only_change_mode):
+ """Send status email.
+
+ Args:
+ prev_time: the date string such as '2011-10-09-11'. This format has been
+ used in this analyzer.
+ analyzer_result_map: current analyzer result.
+ diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys.
+ The values of the map are the result of |GetDiffBetweenMaps()|.
+ The element has two lists of test cases. One (with index 0) is for
+ test names that are in the current result but NOT in the previous
+ result. The other (with index 1) is for test names that are in the
+ previous results but NOT in the current result.
+ For example (test expectation information is omitted for
+ simplicity),
+ comp_result_map['whole'][0] = ['foo1.html']
+ comp_result_map['whole'][1] = ['foo2.html']
+ This means that current result has 'foo1.html' but it is NOT in the
+ previous result. This also means the previous result has 'foo2.html'
+ but it is NOT in the current result.
+ receiver_email_address: receiver's email address.
+ test_group_name: string representing the test group name (e.g., 'media').
+ appended_text_to_email: a text which is appended at the end of the status
+ email.
+ email_content: an email content string that will be shown on the dashboard.
+ rev_str: a revision string that contains revision information that is sent
+ out in the status email. It is obtained by calling
+ |GetRevisionString()|.
+ email_only_change_mode: send email only when there is a change if this is
+ True. Otherwise, always send email after each run.
+ """
+ if rev_str:
+ email_content += '<br><b>Revision Information:</b>'
+ email_content += rev_str
+ localtime = time.asctime(time.localtime(time.time()))
+ change_str = ''
+ if email_only_change_mode:
+ change_str = 'Status Change '
+ subject = 'Layout Test Analyzer Result %s(%s): %s' % (change_str,
+ test_group_name,
+ localtime)
+ SendEmail('no-reply@chromium.org', [receiver_email_address],
+ subject, email_content + appended_text_to_email)
+
+
+def GetRevisionString(prev_time, current_time, diff_map):
+ """Get a string for revision information during the specified time period.
+
+ Args:
+ prev_time: the previous time as a floating point number expressed
+ in seconds since the epoch, in UTC.
+ current_time: the current time as a floating point number expressed
+ in seconds since the epoch, in UTC. It is typically obtained by
+ time.time() function.
+ diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys.
+ Please refer to |diff_map| in |SendStatusEmail()|.
+
+ Returns:
+ a tuple of strings:
+ 1) full string containing links, author, date, and line for each
+ change in the test expectation file.
+ 2) shorter string containing only links to the change. Used for
+ trend graph annotations.
+ 3) last revision number for the given test group.
+ 4) last revision date for the given test group.
+ """
+ if not diff_map:
+ return ('', '', '', '')
+ testname_map = {}
+ for test_group in ['skip', 'nonskip']:
+ for i in range(2):
+ for (k, _) in diff_map[test_group][i]:
+ testname_map[k] = True
+ rev_infos = TestExpectationsHistory.GetDiffBetweenTimes(prev_time,
+ current_time,
+ testname_map.keys())
+ rev_str = ''
+ simple_rev_str = ''
+ rev = ''
+ rev_date = ''
+ if rev_infos:
+ # Get latest revision number and date.
+ rev = rev_infos[-1][1]
+ rev_date = rev_infos[-1][3]
+ for rev_info in rev_infos:
+ (old_rev, new_rev, author, date, _, target_lines) = rev_info
+
+ # test_expectations.txt was renamed to TestExpectations at r119317.
+ new_path = DEFAULT_TEST_EXPECTATION_PATH
+ if new_rev < 119317:
+ new_path = LEGACY_DEFAULT_TEST_EXPECTATION_PATH
+ old_path = DEFAULT_TEST_EXPECTATION_PATH
+ if old_rev < 119317:
+ old_path = LEGACY_DEFAULT_TEST_EXPECTATION_PATH
+
+ link = REVISION_LOG_URL % (new_path, old_rev, new_rev)
+ rev_str += '<ul><a href="%s">%s->%s</a>\n' % (link, old_rev, new_rev)
+ simple_rev_str = '<a href="%s">%s->%s</a>,' % (link, old_rev, new_rev)
+ rev_str += '<li>%s</li>\n' % author
+ rev_str += '<li>%s</li>\n<ul>' % date
+ for line in target_lines:
+ # Find *.html pattern (test name) and replace it with the link to
+ # flakiness dashboard.
+ test_name_pattern = r'(\S+.html)'
+ match = re.search(test_name_pattern, line)
+ if match:
+ test_name = match.group(1)
+ gpu_link = ''
+ if 'GPU' in line:
+ gpu_link = 'group=%40ToT%20GPU%20Mesa%20-%20chromium.org&'
+ dashboard_link = ('http://test-results.appspot.com/dashboards/'
+ 'flakiness_dashboard.html#%stests=%s') % (
+ gpu_link, test_name)
+ line = line.replace(test_name, '<a href="%s">%s</a>' % (
+ dashboard_link, test_name))
+ # Find bug text and replace it with the link to the bug.
+ bug = Bug(line)
+ if bug.bug_txt:
+ line = '<li>%s</li>\n' % line.replace(bug.bug_txt, str(bug))
+ rev_str += line
+ rev_str += '</ul></ul>'
+ return (rev_str, simple_rev_str, rev, rev_date)
+
+
+def SendEmail(sender_email_address, receivers_email_addresses, subject,
+ message):
+ """Send email using localhost's mail server.
+
+ Args:
+ sender_email_address: sender's email address.
+ receivers_email_addresses: receiver's email addresses.
+ subject: subject string.
+ message: email message.
+ """
+ try:
+ html_top = """
+ <html>
+ <head></head>
+ <body>
+ """
+ html_bot = """
+ </body>
+ </html>
+ """
+ html = html_top + message + html_bot
+ msg = MIMEMultipart('alternative')
+ msg['Subject'] = subject
+ msg['From'] = sender_email_address
+ msg['To'] = receivers_email_addresses[0]
+ part1 = MIMEText(html, 'html')
+ smtp_obj = smtplib.SMTP('localhost')
+ msg.attach(part1)
+ smtp_obj.sendmail(sender_email_address, receivers_email_addresses,
+ msg.as_string())
+ print 'Successfully sent email'
+ except smtplib.SMTPException, ex:
+ print 'Authentication failed:', ex
+ print 'Error: unable to send email'
+ except (socket.gaierror, socket.error, socket.herror), ex:
+ print ex
+ print 'Error: unable to send email'
+
+
+def FindLatestTime(time_list):
+ """Find latest time from |time_list|.
+
+ The current status is compared to the status of the latest file in
+ |RESULT_DIR|.
+
+ Args:
+ time_list: a list of time string in the form of 'Year-Month-Day-Hour'
+ (e.g., 2011-10-23-23). Strings not in this format are ignored.
+
+ Returns:
+ a string representing latest time among the time_list or None if
+ |time_list| is empty or no valid date string in |time_list|.
+ """
+ if not time_list:
+ return None
+ latest_date = None
+ for time_element in time_list:
+ try:
+ item_date = datetime.strptime(time_element, '%Y-%m-%d-%H')
+ if latest_date is None or latest_date < item_date:
+ latest_date = item_date
+ except ValueError:
+ # Do nothing.
+ pass
+ if latest_date:
+ return latest_date.strftime('%Y-%m-%d-%H')
+ else:
+ return None
+
+
+def ReplaceLineInFile(file_path, search_exp, replace_line):
+ """Replace line which has |search_exp| with |replace_line| within a file.
+
+ Args:
+ file_path: the file that is being replaced.
+ search_exp: search expression to find a line to be replaced.
+ replace_line: the new line.
+ """
+ for line in fileinput.input(file_path, inplace=1):
+ if search_exp in line:
+ line = replace_line
+ sys.stdout.write(line)
+
+
+def FindLatestResult(result_dir):
+ """Find the latest result in |result_dir| and read and return them.
+
+ This is used for comparison of analyzer result between current analyzer
+ and most known latest result.
+
+ Args:
+ result_dir: the result directory.
+
+ Returns:
+ A tuple of filename (latest_time) and the latest analyzer result.
+ Returns None if there is no file or no file that matches the file
+ patterns used ('%Y-%m-%d-%H').
+ """
+ dir_list = os.listdir(result_dir)
+ file_name = FindLatestTime(dir_list)
+ if not file_name:
+ return None
+ file_path = os.path.join(result_dir, file_name)
+ return (file_name, AnalyzerResultMap.Load(file_path))
+
+
+def GetDiffBetweenMaps(map1, map2, lookIntoTestExpectationInfo=False):
+ """Get difference between maps.
+
+ Args:
+ map1: analyzer result map to be compared.
+ map2: analyzer result map to be compared.
+ lookIntoTestExpectationInfo: a boolean to indicate whether to compare
+ test expectation information in addition to just the test case names.
+
+ Returns:
+ a tuple of |name1_list| and |name2_list|. |Name1_list| contains all test
+ name and the test expectation information in |map1| but not in |map2|.
+ |Name2_list| contains all test name and the test expectation
+ information in |map2| but not in |map1|.
+ """
+
+ def GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo):
+ """A helper function for GetDiffBetweenMaps.
+
+ Args:
+ map1: analyzer result map to be compared.
+ map2: analyzer result map to be compared.
+ lookIntoTestExpectationInfo: a boolean to indicate whether to compare
+ test expectation information in addition to just the test case names.
+
+ Returns:
+ a list of tuples (name, te_info) that are in |map1| but not in |map2|.
+ """
+ name_list = []
+ for (name, value1) in map1.iteritems():
+ if name in map2:
+ if lookIntoTestExpectationInfo and 'te_info' in value1:
+ list1 = value1['te_info']
+ list2 = map2[name]['te_info']
+ te_diff = [item for item in list1 if not item in list2]
+ if te_diff:
+ name_list.append((name, te_diff))
+ else:
+ name_list.append((name, value1))
+ return name_list
+
+ return (GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo),
+ GetDiffBetweenMapsHelper(map2, map1, lookIntoTestExpectationInfo))
diff --git a/chromium/media/tools/layout_tests/layouttest_analyzer_helpers_unittest.py b/chromium/media/tools/layout_tests/layouttest_analyzer_helpers_unittest.py
new file mode 100755
index 00000000000..ab14d87aa97
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttest_analyzer_helpers_unittest.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+from datetime import datetime
+import os
+import pickle
+import time
+import unittest
+
+
+import layouttest_analyzer_helpers
+
+
+class TestLayoutTestAnalyzerHelpers(unittest.TestCase):
+
+ def testFindLatestTime(self):
+ time_list = ['2011-08-18-19', '2011-08-18-22', '2011-08-18-21',
+ '2012-01-11-21', '.foo']
+ self.assertEquals(layouttest_analyzer_helpers.FindLatestTime(time_list),
+ '2012-01-11-21')
+
+ def testFindLatestTimeWithEmptyList(self):
+ time_list = []
+ self.assertEquals(layouttest_analyzer_helpers.FindLatestTime(time_list),
+ None)
+
+ def testFindLatestTimeWithNoValidStringInList(self):
+ time_list = ['.foo1', '232232']
+ self.assertEquals(layouttest_analyzer_helpers.FindLatestTime(time_list),
+ None)
+
+ def GenerateTestDataWholeAndSkip(self):
+ """You should call this method if you want to generate test data."""
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ # Remove this first part
+ m = analyzerResultMapBase.result_map['whole']
+ del m['media/video-source-type.html']
+ m = analyzerResultMapBase.result_map['skip']
+ del m['media/track/track-webvtt-tc004-magicheader.html']
+
+ file_path = os.path.join('test_data', 'less')
+ analyzerResultMapBase.Save(file_path)
+
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = AnalyzerResultMap.Load(file_path)
+
+ analyzerResultMapBase.result_map['whole']['add1.html'] = True
+ analyzerResultMapBase.result_map['skip']['add2.html'] = True
+
+ file_path = os.path.join('test_data', 'more')
+ analyzerResultMapBase.Save(file_path)
+
+ def GenerateTestDataNonSkip(self):
+ """You should call this method if you want to generate test data."""
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = AnalyzerResultMap.Load(file_path)
+ m = analyzerResultMapBase.result_map['nonskip']
+ ex = m['media/media-document-audio-repaint.html']
+ te_info_map1 = ex['te_info'][0]
+ te_info_map2 = copy.copy(te_info_map1)
+ te_info_map2['NEWADDED'] = True
+ ex['te_info'].append(te_info_map2)
+ m = analyzerResultMapBase.result_map['nonskip']
+
+ file_path = os.path.join('test_data', 'more_te_info')
+ analyzerResultMapBase.Save(file_path)
+
+ def testCompareResultMapsWholeAndSkip(self):
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+
+ file_path = os.path.join('test_data', 'less')
+ analyzerResultMapLess = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+
+ diff = analyzerResultMapBase.CompareToOtherResultMap(analyzerResultMapLess)
+ self.assertEquals(diff['skip'][0][0][0],
+ 'media/track/track-webvtt-tc004-magicheader.html')
+ self.assertEquals(diff['whole'][0][0][0],
+ 'media/video-source-type.html')
+ file_path = os.path.join('test_data', 'more')
+ analyzerResultMapMore = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ diff = analyzerResultMapBase.CompareToOtherResultMap(analyzerResultMapMore)
+ self.assertEquals(diff['whole'][1][0][0], 'add1.html')
+ self.assertEquals(diff['skip'][1][0][0], 'add2.html')
+
+ def testCompareResultMapsNonSkip(self):
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ file_path = os.path.join('test_data', 'more_te_info')
+ analyzerResultMapMoreTEInfo = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ m = analyzerResultMapBase.CompareToOtherResultMap(
+ analyzerResultMapMoreTEInfo)
+ self.assertTrue('NEWADDED' in m['nonskip'][1][0][1][0])
+
+ def testGetListOfBugsForNonSkippedTests(self):
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ self.assertEquals(
+ len(analyzerResultMapBase.GetListOfBugsForNonSkippedTests().keys()),
+ 10)
+
+ def RunTestGetRevisionString(self, current_time_str, prev_time_str,
+ expected_rev_str, expected_simple_rev_str,
+ expected_rev_number, expected_rev_date,
+ testname, diff_map_none=False):
+ current_time = datetime.strptime(current_time_str, '%Y-%m-%d-%H')
+ current_time = time.mktime(current_time.timetuple())
+ prev_time = datetime.strptime(prev_time_str, '%Y-%m-%d-%H')
+ prev_time = time.mktime(prev_time.timetuple())
+ if diff_map_none:
+ diff_map = None
+ else:
+ diff_map = {
+ 'whole': [[], []],
+ 'skip': [[(testname, 'te_info1')], []],
+ 'nonskip': [[], []],
+ }
+ (rev_str, simple_rev_str, rev_number, rev_date) = (
+ layouttest_analyzer_helpers.GetRevisionString(prev_time, current_time,
+ diff_map))
+ self.assertEquals(rev_str, expected_rev_str)
+ self.assertEquals(simple_rev_str, expected_simple_rev_str)
+ self.assertEquals(rev_number, expected_rev_number)
+ self.assertEquals(rev_date, expected_rev_date)
+
+ def testGetRevisionString(self):
+ expected_rev_str = ('<ul><a href="http://trac.webkit.org/changeset?'
+ 'new=94377@trunk/LayoutTests/platform/chromium/'
+ 'test_expectations.txt&old=94366@trunk/LayoutTests/'
+ 'platform/chromium/test_expectations.txt">94366->'
+ '94377</a>\n'
+ '<li>jamesr@google.com</li>\n'
+ '<li>2011-09-01 18:00:23</li>\n'
+ '<ul><li>-<a href="http://webkit.org/b/63878">'
+ 'BUGWK63878</a> : <a href="http://test-results.'
+ 'appspot.com/dashboards/flakiness_dashboard.html#'
+ 'tests=fast/dom/dom-constructors.html">fast/dom/'
+ 'dom-constructors.html</a> = TEXT</li>\n</ul></ul>')
+ expected_simple_rev_str = ('<a href="http://trac.webkit.org/changeset?'
+ 'new=94377@trunk/LayoutTests/platform/chromium/'
+ 'test_expectations.txt&old=94366@trunk/'
+ 'LayoutTests/platform/chromium/'
+ 'test_expectations.txt">94366->94377</a>,')
+ self.RunTestGetRevisionString('2011-09-02-00', '2011-09-01-00',
+ expected_rev_str, expected_simple_rev_str,
+ 94377, '2011-09-01 18:00:23',
+ 'fast/dom/dom-constructors.html')
+
+ def testGetRevisionStringNoneDiffMap(self):
+ self.RunTestGetRevisionString('2011-09-02-00', '2011-09-01-00', '', '',
+ '', '', '', diff_map_none=True)
+
+ def testGetRevisionStringNoMatchingTest(self):
+ self.RunTestGetRevisionString('2011-09-01-00', '2011-09-02-00', '', '',
+ '', '', 'foo1.html')
+
+ def testReplaceLineInFile(self):
+ file_path = os.path.join('test_data', 'inplace.txt')
+ f = open(file_path, 'w')
+ f.write('Hello')
+ f.close()
+ layouttest_analyzer_helpers.ReplaceLineInFile(
+ file_path, 'Hello', 'Goodbye')
+ f = open(file_path, 'r')
+ self.assertEquals(f.readline(), 'Goodbye')
+ f.close()
+ layouttest_analyzer_helpers.ReplaceLineInFile(
+ file_path, 'Bye', 'Hello')
+ f = open(file_path, 'r')
+ self.assertEquals(f.readline(), 'Goodbye')
+ f.close()
+
+ def testFindLatestResultWithNoData(self):
+ self.assertFalse(
+ layouttest_analyzer_helpers.FindLatestResult('test_data'))
+
+ def testConvertToCSVText(self):
+ file_path = os.path.join('test_data', 'base')
+ analyzerResultMapBase = (
+ layouttest_analyzer_helpers.AnalyzerResultMap.Load(file_path))
+ data, issues_txt = analyzerResultMapBase.ConvertToCSVText('11-10-10-2011')
+ self.assertEquals(data, '11-10-10-2011,204,36,10,95')
+ expected_issues_txt = """\
+BUGWK,66310,TEXT PASS,media/media-blocked-by-beforeload.html,DEBUG TEXT PASS,\
+media/video-source-error.html,
+BUGCR,86714,GPU IMAGE CRASH MAC,media/video-zoom.html,GPU IMAGE CRASH MAC,\
+media/video-controls-rendering.html,
+BUGCR,74102,GPU IMAGE PASS LINUX,media/video-controls-rendering.html,
+BUGWK,55718,TEXT IMAGE IMAGE+TEXT,media/media-document-audio-repaint.html,
+BUGCR,78376,TIMEOUT,http/tests/media/video-play-stall-seek.html,
+BUGCR,59415,WIN TEXT TIMEOUT PASS,media/video-loop.html,
+BUGCR,72223,IMAGE PASS,media/video-frame-accurate-seek.html,
+BUGCR,75354,TEXT IMAGE IMAGE+TEXT,media/media-document-audio-repaint.html,
+BUGCR,73609,TEXT,http/tests/media/video-play-stall.html,
+BUGWK,64003,DEBUG TEXT MAC PASS,media/video-delay-load-event.html,
+"""
+ self.assertEquals(issues_txt, expected_issues_txt)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/layout_tests/layouttest_analyzer_runner.py b/chromium/media/tools/layout_tests/layouttest_analyzer_runner.py
new file mode 100755
index 00000000000..90a71009671
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttest_analyzer_runner.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Main function to run the layout test analyzer.
+
+The purpose of this script is to run the layout test analyzer for various
+teams based on the run configuration file in CSV format. The CSV file is based
+on https://sites.google.com/a/chromium.org/dev/developers/testing/
+webkit-layout-tests/layout-test-stats-1.
+"""
+
+import optparse
+import os
+import shutil
+from subprocess import Popen
+
+# TODO(shadi): Re-examine the need of external files. Inline data instead?
+DEFAULT_RUN_CONFIG = {
+ # test_group_name: ('test_files.csv', 'report_email_address')
+ 'media': ('testname/media.csv', 'layout-test-analyzer-result@google.com')
+}
+
+# Predefined result/graph directory.
+DEFAULT_RESULT_DIR = 'result'
+DEFAULT_GRAPH_DIR = 'graph'
+
+
+def ParseOption():
+ """Parse command-line options using OptionParser.
+
+ Returns:
+ an object containing all command-line option information.
+ """
+ option_parser = optparse.OptionParser()
+ option_parser.add_option('-d', '--result-directory-location',
+ dest='result_directory_location',
+ help=('Name of result directory location '
+ '(default to %default)'),
+ default=DEFAULT_RESULT_DIR)
+ option_parser.add_option('-p', '--graph-directory-location',
+ dest='graph_directory_location',
+ help=('Name of graph directory location '
+ '(default to %default)'),
+ default=DEFAULT_GRAPH_DIR)
+ option_parser.add_option('-e', '--email-only-change-mode',
+ dest='email_only_change_mode',
+ help=('With this mode, email is sent out '
+ 'only when there is a change in the '
+ 'analyzer result compared to the previous '
+ 'result (off by default)'),
+ action='store_true', default=False)
+ option_parser.add_option('-z', '--issue-detail-mode',
+ dest='issue_detail_mode',
+ help=('With this mode, email includes issue details'
+ ' including links to the flakiness dashboard'
+ ' (off by default)'),
+ action='store_true', default=False)
+ return option_parser.parse_args()[0]
+
+
+def GenerateDashboardHTMLFile(file_name, test_group_list):
+ """Generate dashboard HTML file.
+
+ Currently, it is simple table that shows all the analyzer results.
+
+ Args:
+ file_name: the file name of the dashboard.
+ test_group_list: a list of test group names such as 'media' or 'composite'.
+ """
+ file_object = open(file_name, 'wb')
+ legend_txt = """
+<style type="text/css">
+th {
+ width: 30px; overflow: hidden;
+}
+tr.d0 td {
+ background-color: #CC9999; color: black;
+ text-align: right;
+ width: 30px; overflow: hidden;
+}
+tr.d1 td {
+ background-color: #9999CC; color: black;
+ text-align: right;
+ width: 30px; overflow: hidden;
+}
+</style>
+<h2>Chromium Layout Test Analyzer Result</h2>
+Legend:
+<ul>
+<li>#Tests: the number of tests for the given test group
+<li>#Skipped Tests: the number of tests that are skipped in the
+<a href='http://svn.webkit.org/repository/webkit/trunk/LayoutTests/platform/\
+chromium/test_expectations.txt'>test expectaion file</a> (e.g., BUGWK60877
+SKIP : loader/navigation-while-deferring-loads.html = FAIL)
+<li>#Non-Skipped Failing Tests: the number of tests that appeared in the
+test expectation file and were not skipped.
+<li>Failing rate: #NonSkippedFailing / (#Tests - #Skipped)
+<li>Passing rate: 100 - (Failing rate)
+</ul>
+ """
+ file_object.write(legend_txt)
+ file_object.write('<table border="1">')
+ file_object.write('<tr><th>Base Directory</th>')
+ file_object.write('<th>Trend Graph</th>')
+ file_object.write('<th>#Tests</th>')
+ file_object.write('<th>#Skipped Tests</th>')
+ file_object.write('<th>#Non-Skipped Failing Tests</th>')
+ file_object.write('<th>Failing Rate</th>')
+ file_object.write('<th>Passing Rate</th>')
+ file_object.write('<th>Last Revision Number</th>')
+ file_object.write('<th>Last Revision Date</th>')
+ file_object.write('<th>Owner Email</th>')
+ file_object.write('<th>Bug Information</th></tr>\n')
+ test_group_list.sort()
+ for i, test_group in enumerate(test_group_list):
+ file_object.write('<tr class="d' + str(i % 2) + '">\n')
+ file_object.write('<td>' + test_group + '</td>\n')
+ file_object.write('</tr>\n')
+ file_object.write('</table>')
+ file_object.close()
+
+
+# TODO(shadi): Use only one file with main()! Remove this file in favor of
+# layouttest_analyzer.py main().
+def main():
+ """A main function for the analyzer runner."""
+ options = ParseOption()
+ run_config_map = DEFAULT_RUN_CONFIG
+ test_group_list = run_config_map.keys()
+ dashboard_file_location = os.path.join(options.graph_directory_location,
+ 'index.html')
+ if not os.path.exists(dashboard_file_location):
+ GenerateDashboardHTMLFile(dashboard_file_location, test_group_list)
+ for test_group in test_group_list:
+ # Prepare the result if it does not exist.
+ # The directory name should be changed to avoid collision
+ # with the file separator.
+ test_group_name_for_data = test_group.replace('/', '_')
+ result_dir = os.path.join(options.result_directory_location,
+ test_group_name_for_data)
+ if not os.path.exists(result_dir):
+ os.mkdir(result_dir)
+ graph_file = os.path.join(options.graph_directory_location,
+ test_group_name_for_data + '.html')
+ if not os.path.exists(graph_file):
+ # Copy the template file.
+ shutil.copy(os.path.join('graph', 'graph.html'),
+ graph_file)
+ os.chmod(graph_file, 0744)
+ cmd = ('python layouttest_analyzer.py -x %s -d %s -t %s'
+ ' -q %s ') % (
+ test_group, result_dir, graph_file, dashboard_file_location)
+ if run_config_map[test_group][0]:
+ cmd += '-n ' + run_config_map[test_group][0] + ' '
+ if run_config_map[test_group][1]:
+ cmd += '-r ' + run_config_map[test_group][1] + ' '
+ if options.email_only_change_mode:
+ cmd += ' -c '
+ if options.issue_detail_mode:
+ cmd += ' -z '
+ print 'Running ' + cmd
+ proc = Popen(cmd, shell=True)
+ proc.communicate()
+
+
+if '__main__' == __name__:
+ main()
diff --git a/chromium/media/tools/layout_tests/layouttests.py b/chromium/media/tools/layout_tests/layouttests.py
new file mode 100644
index 00000000000..8d3003815bb
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttests.py
@@ -0,0 +1,244 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Layout tests module that is necessary for the layout analyzer.
+
+Layout tests are stored in an SVN repository and LayoutTestCaseManager collects
+these layout test cases (including description).
+"""
+
+import copy
+import csv
+import locale
+import re
+import sys
+import urllib2
+
+import pysvn
+
+# LayoutTests SVN root location.
+DEFAULT_LAYOUTTEST_LOCATION = (
+ 'http://src.chromium.org/blink/trunk/LayoutTests/')
+# LayoutTests SVN view link
+DEFAULT_LAYOUTTEST_SVN_VIEW_LOCATION = (
+ 'http://src.chromium.org/viewvc/blink/trunk/LayoutTests/')
+
+
+# When parsing the test HTML file and finding the test description,
+# this script tries to find the test description using sentences
+# starting with these keywords. This is adhoc but it is the only way
+# since there is no standard for writing test description.
+KEYWORDS_FOR_TEST_DESCRIPTION = ['This test', 'Tests that', 'Test ']
+
+# If cannot find the keywords, this script tries to find test case
+# description by the following tags.
+TAGS_FOR_TEST_DESCRIPTION = ['title', 'p', 'div']
+
+# If cannot find the tags, this script tries to find the test case
+# description in the sentence containing following words.
+KEYWORD_FOR_TEST_DESCRIPTION_FAIL_SAFE = ['PASSED ', 'PASS:']
+
+
+class LayoutTests(object):
+ """A class to store test names in layout tests.
+
+ The test names (including regular expression patterns) are read from a CSV
+ file and used for getting layout test names from repository.
+ """
+
+ def __init__(self, layouttest_root_path=DEFAULT_LAYOUTTEST_LOCATION,
+ parent_location_list=None, filter_names=None,
+ recursion=False):
+ """Initialize LayoutTests using root and CSV file.
+
+ Args:
+ layouttest_root_path: A location string where layout tests are stored.
+ parent_location_list: A list of parent directories that are needed for
+ getting layout tests.
+ filter_names: A list of test name patterns that are used for filtering
+ test names (e.g., media/*.html).
+ recursion: a boolean indicating whether the test names are sought
+ recursively.
+ """
+
+ if layouttest_root_path.startswith('http://'):
+ name_map = self.GetLayoutTestNamesFromSVN(parent_location_list,
+ layouttest_root_path,
+ recursion)
+ else:
+ # TODO(imasaki): support other forms such as CSV for reading test names.
+ pass
+ self.name_map = copy.copy(name_map)
+ if filter_names:
+ # Filter names.
+ for lt_name in name_map.iterkeys():
+ match = False
+ for filter_name in filter_names:
+ if re.search(filter_name, lt_name):
+ match = True
+ break
+ if not match:
+ del self.name_map[lt_name]
+ # We get description only for the filtered names.
+ for lt_name in self.name_map.iterkeys():
+ self.name_map[lt_name] = 'No description available'
+
+ @staticmethod
+ def ExtractTestDescription(txt):
+ """Extract the description description from test code in HTML.
+
+ Currently, we have 4 rules described in the code below.
+ (This example falls into rule 1):
+ <p>
+ This tests the intrinsic size of a video element is the default
+ 300,150 before metadata is loaded, and 0,0 after
+ metadata is loaded for an audio-only file.
+ </p>
+ The strategy is very adhoc since the original test case files
+ (in HTML format) do not have standard way to store test description.
+
+ Args:
+ txt: A HTML text which may or may not contain test description.
+
+ Returns:
+ A string that contains test description. Returns 'UNKNOWN' if the
+ test description is not found.
+ """
+ # (1) Try to find test description that contains keywords such as
+ # 'test that' and surrounded by p tag.
+ # This is the most common case.
+ for keyword in KEYWORDS_FOR_TEST_DESCRIPTION:
+ # Try to find <p> and </p>.
+ pattern = r'<p>(.*' + keyword + '.*)</p>'
+ matches = re.search(pattern, txt)
+ if matches is not None:
+ return matches.group(1).strip()
+
+ # (2) Try to find it by using more generic keywords such as 'PASS' etc.
+ for keyword in KEYWORD_FOR_TEST_DESCRIPTION_FAIL_SAFE:
+ # Try to find new lines.
+ pattern = r'\n(.*' + keyword + '.*)\n'
+ matches = re.search(pattern, txt)
+ if matches is not None:
+ # Remove 'p' tag.
+ text = matches.group(1).strip()
+ return text.replace('<p>', '').replace('</p>', '')
+
+ # (3) Try to find it by using HTML tag such as title.
+ for tag in TAGS_FOR_TEST_DESCRIPTION:
+ pattern = r'<' + tag + '>(.*)</' + tag + '>'
+ matches = re.search(pattern, txt)
+ if matches is not None:
+ return matches.group(1).strip()
+
+ # (4) Try to find it by using test description and remove 'p' tag.
+ for keyword in KEYWORDS_FOR_TEST_DESCRIPTION:
+ # Try to find <p> and </p>.
+ pattern = r'\n(.*' + keyword + '.*)\n'
+ matches = re.search(pattern, txt)
+ if matches is not None:
+ # Remove 'p' tag.
+ text = matches.group(1).strip()
+ return text.replace('<p>', '').replace('</p>', '')
+
+ # (5) cannot find test description using existing rules.
+ return 'UNKNOWN'
+
+ @staticmethod
+ def GetLayoutTestNamesFromSVN(parent_location_list,
+ layouttest_root_path, recursion):
+ """Get LayoutTest names from SVN.
+
+ Args:
+ parent_location_list: a list of locations of parent directories. This is
+ used when getting layout tests using PySVN.list().
+ layouttest_root_path: the root path of layout tests directory.
+ recursion: a boolean indicating whether the test names are sought
+ recursively.
+
+ Returns:
+ a map containing test names as keys for de-dupe.
+ """
+ client = pysvn.Client()
+ # Get directory structure in the repository SVN.
+ name_map = {}
+ for parent_location in parent_location_list:
+ if parent_location.endswith('/'):
+ full_path = layouttest_root_path + parent_location
+ try:
+ file_list = client.list(full_path, recurse=recursion)
+ for file_name in file_list:
+ if sys.stdout.isatty():
+ default_encoding = sys.stdout.encoding
+ else:
+ default_encoding = locale.getpreferredencoding()
+ file_name = file_name[0].repos_path.encode(default_encoding)
+ # Remove the word '/truck/LayoutTests'.
+ file_name = file_name.replace('/trunk/LayoutTests/', '')
+ if file_name.endswith('.html'):
+ name_map[file_name] = True
+ except:
+ print 'Unable to list tests in %s.' % full_path
+ return name_map
+
+ @staticmethod
+ def GetLayoutTestNamesFromCSV(csv_file_path):
+ """Get layout test names from CSV file.
+
+ Args:
+ csv_file_path: the path for the CSV file containing test names (including
+ regular expression patterns). The CSV file content has one column and
+ each row contains a test name.
+
+ Returns:
+ a list of test names in string.
+ """
+ file_object = file(csv_file_path, 'r')
+ reader = csv.reader(file_object)
+ names = [row[0] for row in reader]
+ file_object.close()
+ return names
+
+ @staticmethod
+ def GetParentDirectoryList(names):
+ """Get parent directory list from test names.
+
+ Args:
+ names: a list of test names. The test names also have path information as
+ well (e.g., media/video-zoom.html).
+
+ Returns:
+ a list of parent directories for the given test names.
+ """
+ pd_map = {}
+ for name in names:
+ p_dir = name[0:name.rfind('/') + 1]
+ pd_map[p_dir] = True
+ return list(pd_map.iterkeys())
+
+ def JoinWithTestExpectation(self, test_expectations):
+ """Join layout tests with the test expectation file using test name as key.
+
+ Args:
+ test_expectations: a test expectations object.
+
+ Returns:
+ test_info_map contains test name as key and another map as value. The
+ other map contains test description and the test expectation
+ information which contains keyword (e.g., 'GPU') as key (we do
+ not care about values). The map data structure is used since we
+ have to look up these keywords several times.
+ """
+ test_info_map = {}
+ for (lt_name, desc) in self.name_map.items():
+ test_info_map[lt_name] = {}
+ test_info_map[lt_name]['desc'] = desc
+ for (te_name, te_info) in (
+ test_expectations.all_test_expectation_info.items()):
+ if te_name == lt_name or (
+ te_name in lt_name and te_name.endswith('/')):
+ # Only keep the first match when found.
+ test_info_map[lt_name]['te_info'] = te_info
+ break
+ return test_info_map
diff --git a/chromium/media/tools/layout_tests/layouttests_unittest.py b/chromium/media/tools/layout_tests/layouttests_unittest.py
new file mode 100755
index 00000000000..7fb44dffe2c
--- /dev/null
+++ b/chromium/media/tools/layout_tests/layouttests_unittest.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+from layouttests import LayoutTests
+from test_expectations import TestExpectations
+
+
+class TestLayoutTests(unittest.TestCase):
+ """Unit tests for the LayoutTests class."""
+
+ def testJoinWithTestExpectation(self):
+ layouttests = LayoutTests(parent_location_list=['media/'])
+ test_expectations = TestExpectations()
+ test_info_map = layouttests.JoinWithTestExpectation(test_expectations)
+ # TODO(imasaki): have better assertion below. Currently, the test
+ # expectation file is obtained dynamically so the strict assertion is
+ # impossible.
+ self.assertTrue(any(['media/' in k for k in test_info_map.keys()]),
+ msg=('Analyzer result should contain at least one '
+ 'media test cases since we only retrieved media '
+ 'related test'))
+
+ def testGetTestDescriptionsFromSVN(self):
+ desc1 = LayoutTests.GetTestDescriptionFromSVN(
+ 'media/video-play-empty-events.html')
+ self.assertEquals(desc1,
+ ('Test that play() from EMPTY network state triggers '
+ 'load() and async play event.'),
+ msg='Extracted test description is wrong')
+ desc2 = LayoutTests.GetTestDescriptionFromSVN('jquery/data.html')
+ self.assertEquals(desc2, 'UNKNOWN',
+ msg='Extracted test description is wrong')
+
+ def testGetParentDirectoryList(self):
+ testname_list = ['hoge1/hoge2/hoge3.html', 'hoge1/x.html',
+ 'hoge1/hoge2/hoge4.html']
+ expected_result = ['hoge1/', 'hoge1/hoge2/']
+ self.assertEquals(LayoutTests.GetParentDirectoryList(testname_list),
+ expected_result)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/layout_tests/result/2011-08-19-11 b/chromium/media/tools/layout_tests/result/2011-08-19-11
new file mode 100644
index 00000000000..e020b9e16f5
--- /dev/null
+++ b/chromium/media/tools/layout_tests/result/2011-08-19-11
@@ -0,0 +1,1891 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/track/track-webvtt-tc004-magicheader.html'
+p6
+(dp7
+S'desc'
+p8
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p9
+sS'te_info'
+p10
+(lp11
+(dp12
+S'SKIP'
+p13
+I01
+sS'TIMEOUT'
+p14
+I01
+sS'Comments'
+p15
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p16
+sS'Bugs'
+p17
+(lp18
+S'BUGWK43668'
+p19
+asassS'media/audio-delete-while-step-button-clicked.html'
+p20
+(dp21
+g8
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p22
+sg10
+(lp23
+(dp24
+S'FAIL'
+p25
+I01
+sg13
+I01
+sg17
+(lp26
+S'BUGCR25375'
+p27
+aS'BUGCR59399'
+p28
+asg15
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p29
+sassS'media/restore-from-page-cache.html'
+p30
+(dp31
+g8
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p32
+sg10
+(lp33
+(dp34
+g13
+I01
+sS'WONTFIX'
+p35
+I01
+sg14
+I01
+sg15
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p36
+sg17
+(lp37
+S'BUGCR19635'
+p38
+asassS'media/context-menu-actions.html'
+p39
+(dp40
+g8
+S'Test the various actions available in the HTML5 media element context-menu.'
+p41
+sg10
+(lp42
+(dp43
+S'CRASH'
+p44
+I01
+sg13
+I01
+sg17
+(lp45
+S'BUGCR59665'
+p46
+aS'BUGWK45021'
+p47
+asg15
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p48
+sg14
+I01
+sS'PASS'
+p49
+I01
+sassS'media/track/track-webvtt-tc005-headercomment.html'
+p50
+(dp51
+g8
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p52
+sg10
+g11
+ssS'http/tests/media/video-cross-site.html'
+p53
+(dp54
+g8
+S'media file redirects to another site'
+p55
+sg10
+(lp56
+(dp57
+g13
+I01
+sg15
+S' QuickTime reference movies not supported.'
+p58
+sg14
+I01
+sg49
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-data-url.html'
+p59
+(dp60
+g8
+S'Test that audio element can use a data: url'
+p61
+sg10
+(lp62
+(dp63
+g13
+I01
+sg17
+(lp64
+S'BUGCR16779'
+p65
+asg15
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/video-canvas-alpha.html'
+p67
+(dp68
+g8
+S'UNKNOWN'
+p69
+sg10
+(lp70
+(dp71
+g13
+I01
+sS'IMAGE'
+p72
+I01
+sg17
+(lp73
+S'BUGCR74979'
+p74
+asg15
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p75
+sS'MAC'
+p76
+I01
+sS'GPU'
+p77
+I01
+sassS'media/video-can-play-type.html'
+p78
+(dp79
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p80
+sg10
+(lp81
+(dp82
+g13
+I01
+sg17
+(lp83
+S'BUGCR16779'
+p84
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-captions.html'
+p85
+(dp86
+g8
+S'Test media element close caption API.'
+p87
+sg10
+(lp88
+(dp89
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p90
+sg17
+(lp91
+S'BUGCR28301'
+p92
+asassS'media/media-can-play-mpeg-audio.html'
+p93
+(dp94
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p95
+sg10
+(lp96
+(dp97
+g13
+I01
+sg35
+I01
+sg17
+(lp98
+S'BUGCR16779'
+p99
+asg15
+g66
+sS'TEXT'
+p100
+I01
+sassS'media/track/track-webvtt-tc011-blanklines.html'
+p101
+(dp102
+g8
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p103
+sg10
+g11
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p104
+(dp105
+g8
+S'Tests cues that are temporally out of order (we allow this).'
+p106
+sg10
+g11
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p107
+(dp108
+g8
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p109
+sg10
+g11
+ssS'media/video-size-intrinsic-scale.html'
+p110
+(dp111
+g8
+S'&lt;video&gt; element intrinsic size test'
+p112
+sg10
+(lp113
+(dp114
+g13
+I01
+sg17
+(lp115
+S'BUGCR16779'
+p116
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-mpeg4-supported.html'
+p117
+(dp118
+g8
+S'Test that the audio element supports M4A files.'
+p119
+sg10
+(lp120
+(dp121
+g13
+I01
+sg17
+(lp122
+S'BUGCR16779'
+p123
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-fullscreen-not-in-document.html'
+p124
+(dp125
+g8
+S'Test media element fullscreen API when an element is not in the DOM.'
+p126
+sg10
+(lp127
+(dp128
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p129
+sg17
+(lp130
+S'BUGCR16735'
+p131
+asassS'media/audio-mpeg-supported.html'
+p132
+(dp133
+g8
+S'Test that the audio element supports MPEG files.'
+p134
+sg10
+(lp135
+(dp136
+g13
+I01
+sg17
+(lp137
+S'BUGCR16779'
+p138
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc003-newlines.html'
+p139
+(dp140
+g8
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p141
+sg10
+g11
+ssS'media/video-document-types.html'
+p142
+(dp143
+g8
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p144
+sg10
+(lp145
+(dp146
+g13
+I01
+sg17
+(lp147
+S'BUGCR16779'
+p148
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc002-bom.html'
+p149
+(dp150
+g8
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p151
+sg10
+g11
+ssS'media/video-does-not-loop.html'
+p152
+(dp153
+g8
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p154
+sg10
+(lp155
+(dp156
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p157
+sassS'media/track/track-webvtt-tc000-empty.html'
+p158
+(dp159
+g8
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p160
+sg10
+g11
+ssS'media/media-can-play-mpeg4-video.html'
+p161
+(dp162
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p163
+sg10
+(lp164
+(dp165
+g13
+I01
+sg35
+I01
+sg17
+(lp166
+S'BUGWK45102'
+p167
+asg15
+g66
+sg100
+I01
+sassS'compositing/video/video-background-color.html'
+p168
+(dp169
+g8
+S'Video with background color'
+p170
+sg10
+(lp171
+(dp172
+g25
+I01
+sg13
+I01
+sg35
+I01
+sg17
+(lp173
+S'BUGWK55519'
+p174
+asg15
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p175
+sassS'media/track/track-webvtt-tc010-notimings.html'
+p176
+(dp177
+g8
+S'Tests cue without timings are ignored.'
+p178
+sg10
+g11
+ssS'media/video-timeupdate-reverse-play.html'
+p179
+(dp180
+g8
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p181
+sg10
+(lp182
+(dp183
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p184
+sg17
+(lp185
+S'BUGCR33099'
+p186
+asassS'http/tests/media/video-buffered.html'
+p187
+(dp188
+g8
+g69
+sg10
+(lp189
+(dp190
+g13
+I01
+sg17
+(lp191
+S'BUGCR49165'
+p192
+asg15
+S' video.buffered multiple TimeRanges support.'
+p193
+sg49
+I01
+sassS'media/track/track-webvtt-tc001-utf8.html'
+p194
+(dp195
+g8
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p196
+sg10
+g11
+ssS'media/track/track-webvtt-tc013-settings.html'
+p197
+(dp198
+g8
+S'Tests WebVTT settings.'
+p199
+sg10
+g11
+ssS'media/media-fullscreen-inline.html'
+p200
+(dp201
+g8
+S'Test media element fullscreen API when an element is in the DOM.'
+p202
+sg10
+(lp203
+(dp204
+g13
+I01
+sg14
+I01
+sg15
+g129
+sg17
+(lp205
+S'BUGCR16735'
+p206
+asassS'media/track/track-webvtt-tc007-cuenoid.html'
+p207
+(dp208
+g8
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p209
+sg10
+g11
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p210
+(dp211
+g8
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p212
+sg10
+g11
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p213
+(dp214
+g8
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p215
+sg10
+g11
+ssS'media/video-element-other-namespace-crash.html'
+p216
+(dp217
+g8
+g69
+sg10
+(lp218
+(dp219
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+g66
+sg17
+(lp220
+S'BUGCR68289'
+p221
+asassS'media/video-reverse-play-duration.html'
+p222
+(dp223
+g8
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p224
+sg10
+(lp225
+(dp226
+g13
+I01
+sg14
+I01
+sg15
+g184
+sg17
+(lp227
+S'BUGCR33099'
+p228
+asasssS'whole'
+p229
+(dp230
+S'media/video-source-type.html'
+p231
+(dp232
+g8
+S'&lt;source&gt; @type attribute'
+p233
+ssS'media/media-startTime.html'
+p234
+(dp235
+g8
+S"Test the, so far unused, 'startTime' attribute."
+p236
+ssS'media/video-src-set.html'
+p237
+(dp238
+g8
+S'Test that setting src attribute triggers load'
+p239
+ssg20
+g21
+sS'media/video-played-ranges-1.html'
+p240
+(dp241
+g8
+S"Test of the media element 'played' attribute, ranges part 1."
+p242
+ssS'media/video-layer-crash.html'
+p243
+(dp244
+g8
+S'Test dynamic removal of transformed and reflected video'
+p245
+ssS'http/tests/media/video-play-stall-seek.html'
+p246
+(dp247
+g8
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p248
+sg10
+(lp249
+(dp250
+g14
+I01
+sg15
+S' Timing out.'
+p251
+sg17
+(lp252
+S'BUGCR78376'
+p253
+asassg59
+g60
+sg78
+g79
+sg85
+g86
+sS'http/tests/media/video-referer.html'
+p254
+(dp255
+g8
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p256
+ssS'media/video-source-removed.html'
+p257
+(dp258
+g8
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p259
+ssS'media/unsupported-tracks.html'
+p260
+(dp261
+g8
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p262
+ssg117
+g118
+sS'media/audio-no-installed-engines.html'
+p263
+(dp264
+g8
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p265
+ssg124
+g125
+sS'media/video-dom-src.html'
+p266
+(dp267
+g8
+g69
+ssS'media/media-blocked-by-willsendrequest.html'
+p268
+(dp269
+g8
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p270
+ssS'media/video-error-does-not-exist.html'
+p271
+(dp272
+g8
+S'Test that the media element is in correct state after load fails.'
+p273
+ssS'media/video-play-pause-events.html'
+p274
+(dp275
+g8
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p276
+ssS'media/video-display-none-crash.html'
+p277
+(dp278
+g8
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p279
+ssS'media/video-src-plus-source.html'
+p280
+(dp281
+g8
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p282
+ssS'media/video-source-none-supported.html'
+p283
+(dp284
+g8
+S'no usable &lt;source&gt; test'
+p285
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p286
+(dp287
+g8
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p288
+ssg152
+g153
+sS'media/video-src.html'
+p289
+(dp290
+g8
+g69
+ssS'media/audio-controls-rendering.html'
+p291
+(dp292
+g8
+S'Test controls placement.'
+p293
+ssg168
+g169
+sS'media/video-source-inserted.html'
+p294
+(dp295
+g8
+S'networkState after inserting &lt;source&gt; test'
+p296
+ssS'media/media-can-play-octet-stream.html'
+p297
+(dp298
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p299
+ssS'media/constructors.html'
+p300
+(dp301
+g8
+S'Test that media constructors behave consistently.'
+p302
+ssS'media/video-source-media.html'
+p303
+(dp304
+g8
+g69
+ssg187
+g188
+sS'http/tests/security/local-video-source-from-remote.html'
+p305
+(dp306
+g8
+S'This test only behaves correctly in DRT'
+p307
+ssg194
+g195
+sS'media/video-source-type-params.html'
+p308
+(dp309
+g8
+g69
+ssS'fast/canvas/webgl/context-lost.html'
+p310
+(dp311
+g8
+S'debug("Test valid context");'
+p312
+ssS'media/media-can-play-wav-audio.html'
+p313
+(dp314
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p315
+ssS'media/video-source-error.html'
+p316
+(dp317
+g8
+S'&lt;video&gt; and &lt;source&gt; error test'
+p318
+sg10
+(lp319
+(dp320
+S'DEBUG'
+p321
+I01
+sg100
+I01
+sg17
+(lp322
+S'BUGWK66310'
+p323
+asg15
+S''
+p324
+sg49
+I01
+sassS'media/video-no-audio.html'
+p325
+(dp326
+g8
+S'Movie with no audio track. The volume button should not render.'
+p327
+ssS'media/svg-as-image-with-media-blocked.html'
+p328
+(dp329
+g8
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p330
+ssg207
+g208
+sg107
+g108
+sS'media/video-click-dblckick-standalone.html'
+p331
+(dp332
+g8
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p333
+ssS'media/video-pause-immediately.html'
+p334
+(dp335
+g8
+S'Test that pausing the media element has an immediate effect on the clock.'
+p336
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p337
+(dp338
+g8
+g69
+ssg222
+g223
+sS'http/tests/security/local-video-src-from-remote.html'
+p339
+(dp340
+g8
+S'This test only works in DRT'
+p341
+ssg200
+g201
+sS'media/video-controls-in-media-document.html'
+p342
+(dp343
+g8
+g69
+ssS'media/remove-from-document-no-load.html'
+p344
+(dp345
+g8
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p346
+ssS'media/video-currentTime.html'
+p347
+(dp348
+g8
+g69
+ssS'media/video-frame-accurate-seek.html'
+p349
+(dp350
+g8
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p351
+sg10
+(lp352
+(dp353
+g72
+I01
+sg17
+(lp354
+S'BUGCR72223'
+p355
+asg15
+g324
+sg49
+I01
+sassg30
+g31
+sg39
+g40
+sS'media/media-controls-clone-crash.html'
+p356
+(dp357
+g8
+S'Test passes if it does not crash.'
+p358
+ssg50
+g51
+sS'media/controls-css-overload.html'
+p359
+(dp360
+g8
+S"Testing that overloading some controls doesn't crash the browser"
+p361
+ssS'media/video-display-aspect-ratio.html'
+p362
+(dp363
+g8
+g69
+ssS'media/video-currentTime-set.html'
+p364
+(dp365
+g8
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p366
+ssS'media/media-blocked-by-beforeload.html'
+p367
+(dp368
+g8
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p369
+sg10
+(lp370
+(dp371
+g100
+I01
+sg17
+(lp372
+S'BUGWK66310'
+p373
+asg15
+g324
+sg49
+I01
+sassg104
+g105
+sS'media/video-controls-visible-audio-only.html'
+p374
+(dp375
+g8
+S'This test only runs in DRT!'
+p376
+ssS'http/tests/media/video-play-progress.html'
+p377
+(dp378
+g8
+S'Test that at least one progress event is fired after starting to load the video.'
+p379
+ssg110
+g111
+sS'media/video-source-moved.html'
+p380
+(dp381
+g8
+S'moving &lt;source&gt; element test'
+p382
+ssg101
+g102
+sS'media/video-src-none.html'
+p383
+(dp384
+g8
+g69
+ssS'media/video-controls-zoomed.html'
+p385
+(dp386
+g8
+S'This test only runs in DRT!'
+p387
+ssS'media/video-controls.html'
+p388
+(dp389
+g8
+S"Test 'controls' attribute"
+p390
+ssS'media/controls-without-preload.html'
+p391
+(dp392
+g8
+S'The controls should not depend on preload value.'
+p393
+ssS'media/video-played-collapse.html'
+p394
+(dp395
+g8
+S"Test of the media element 'played' attribute"
+p396
+ssS'compositing/self-painting-layers.html'
+p397
+(dp398
+g8
+S'Self painting layers'
+p399
+ssS'media/audio-controls-do-not-fade-out.html'
+p400
+(dp401
+g8
+S'This tests that audio controls do not fade out when the audio is playing.'
+p402
+ssS'media/media-document-audio-repaint.html'
+p403
+(dp404
+g8
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p405
+sg10
+(lp406
+(dp407
+g100
+I01
+sg72
+I01
+sg17
+(lp408
+S'BUGCR75354'
+p409
+aS'BUGWK55718'
+p410
+asg15
+S' This test needs completely new baselines.'
+p411
+sS'IMAGE+TEXT'
+p412
+I01
+sa(dp413
+S'NEWADDED'
+p414
+I01
+sg100
+I01
+sg72
+I01
+sg17
+g408
+sg15
+g411
+sg412
+I01
+sassS'compositing/geometry/video-opacity-overlay.html'
+p415
+(dp416
+g8
+S'Video overlay'
+p417
+ssS'media/video-source-error-no-candidate.html'
+p418
+(dp419
+g8
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p420
+ssS'media/audio-constructor.html'
+p421
+(dp422
+g8
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p423
+ssS'media/controls-styling.html'
+p424
+(dp425
+g8
+S'The look of the controls should not change.'
+p426
+ssS'media/video-buffered.html'
+p427
+(dp428
+g8
+g69
+ssS'media/event-attributes.html'
+p429
+(dp430
+g8
+g69
+ssg176
+g177
+sg179
+g180
+sS'http/tests/media/text-served-as-text.html'
+p431
+(dp432
+g8
+S"text file served as 'text/plain'"
+p433
+ssS'http/tests/media/video-cancel-load.html'
+p434
+(dp435
+g8
+S'Cancel loading a video file and access its properties afterwards.'
+p436
+ssS'media/unsupported-rtsp.html'
+p437
+(dp438
+g8
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p439
+ssS'media/media-controls-clone.html'
+p440
+(dp441
+g8
+S'<video controls id=v></video><audio controls id=a></audio>'
+p442
+ssS'media/broken-video.html'
+p443
+(dp444
+g8
+S'Test that QuickTime file with broken content generates an error.'
+p445
+ssS'media/video-plays-past-end-of-test.html'
+p446
+(dp447
+g8
+g69
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p448
+(dp449
+g8
+S'WebGL Origin Restrictions Conformance Tests'
+p450
+ssS'media/video-replaces-poster.html'
+p451
+(dp452
+g8
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p453
+ssS'media/video-autoplay.html'
+p454
+(dp455
+g8
+g69
+ssS'media/video-set-rate-from-pause.html'
+p456
+(dp457
+g8
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p458
+ssS'media/video-src-remove.html'
+p459
+(dp460
+g8
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p461
+ssS'media/csp-blocks-video.html'
+p462
+(dp463
+g8
+S"This test passes if it doesn't alert failure."
+p464
+ssS'media/controls-drag-timebar.html'
+p465
+(dp466
+g8
+S'Test that dragging the timebar thumb causes seeks.'
+p467
+ssS'media/audio-constructor-preload.html'
+p468
+(dp469
+g8
+S"Test that Audio() sets 'preload' attribute."
+p470
+ssS'media/video-src-invalid-poster.html'
+p471
+(dp472
+g8
+g69
+ssS'media/adopt-node-crash.html'
+p473
+(dp474
+g8
+S"Tests that we don't crash when moving a video element to a new document."
+p475
+ssS'media/video-playbackrate.html'
+p476
+(dp477
+g8
+S'test playbackRate and defaultPlaybackRate'
+p478
+ssS'media/video-muted.html'
+p479
+(dp480
+g8
+S"Test 'muted' attribute"
+p481
+ssS'media/video-src-change.html'
+p482
+(dp483
+g8
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p484
+ssg216
+g217
+sS'media/video-play-pause-exception.html'
+p485
+(dp486
+g8
+S'Video has no src. Test that the playing event is not dispatched.'
+p487
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p488
+(dp489
+g8
+g69
+ssS'media/audio-play-event.html'
+p490
+(dp491
+g8
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p492
+ssS'media/before-load-member-access.html'
+p493
+(dp494
+g8
+S'Test that accessing member of a non loaded video works.'
+p495
+ssS'media/video-width-height.html'
+p496
+(dp497
+g8
+g69
+ssS'media/audio-repaint.html'
+p498
+(dp499
+g8
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p500
+ssS'media/video-currentTime-delay.html'
+p501
+(dp502
+g8
+S'Test a delay in playing the movie results in a canPlay event.'
+p503
+ssS'media/video-aspect-ratio.html'
+p504
+(dp505
+g8
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p506
+ssS'media/video-transformed.html'
+p507
+(dp508
+g8
+S'Test painting of transformed video'
+p509
+ssS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p510
+(dp511
+g8
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p512
+ssS'media/invalid-media-url-crash.html'
+p513
+(dp514
+g8
+S'Tests that invalid media src url does not result in crash.'
+p515
+ssS'media/video-empty-source.html'
+p516
+(dp517
+g8
+S'Slider drawing with no source. The controls should render correctly.'
+p518
+ssg93
+g94
+sS'media/video-poster.html'
+p519
+(dp520
+g8
+S'Test &lt;video&gt; element with and without a poster.'
+p521
+ssS'media/media-document-audio-size.html'
+p522
+(dp523
+g8
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p524
+ssg132
+g133
+sS'compositing/overflow/overflow-compositing-descendant.html'
+p525
+(dp526
+g8
+S'You should see a green box under the video. If you see red, the test failed.'
+p527
+ssS'media/video-dom-autoplay.html'
+p528
+(dp529
+g8
+g69
+ssS'media/media-ended.html'
+p530
+(dp531
+g8
+S'<b>Test ended by:</b>'
+p532
+ssS'media/video-no-autoplay.html'
+p533
+(dp534
+g8
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p535
+ssS'media/video-zoom.html'
+p536
+(dp537
+g8
+S'150% zoom, with width and height attributes'
+p538
+sg10
+(lp539
+(dp540
+g44
+I01
+sg72
+I01
+sg17
+(lp541
+S'BUGCR86714'
+p542
+asg15
+g324
+sg76
+I01
+sg77
+I01
+sassS'media/video-append-source.html'
+p543
+(dp544
+g8
+g69
+ssg139
+g140
+sS'http/tests/media/pdf-served-as-pdf.html'
+p545
+(dp546
+g8
+S"PDF file served as 'application/pdf'"
+p547
+ssS'media/video-play-empty-events.html'
+p548
+(dp549
+g8
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p550
+ssg149
+g150
+sS'media/audio-only-video-intrinsic-size.html'
+p551
+(dp552
+g8
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p553
+ssg142
+g143
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p554
+(dp555
+g8
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p556
+ssS'media/media-can-play-ogg.html'
+p557
+(dp558
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p559
+ssg6
+g7
+sg158
+g159
+sS'media/video-currentTime-set2.html'
+p560
+(dp561
+g8
+g69
+ssS'media/video-seekable.html'
+p562
+(dp563
+g8
+g69
+ssS'fast/dom/beforeload/video-before-load.html'
+p564
+(dp565
+g8
+g69
+ssS'media/video-played-reset.html'
+p566
+(dp567
+g8
+S"Test of the media element 'played' attribute"
+p568
+ssS'compositing/self-painting-layers2.html'
+p569
+(dp570
+g8
+S'This test should not assert in debug builds.'
+p571
+ssS'media/controls-right-click-on-timebar.html'
+p572
+(dp573
+g8
+S'Test that right clicking on the timebar does not cause a seek.'
+p574
+ssS'media/video-dom-preload.html'
+p575
+(dp576
+g8
+S'consoleWrite("++ Test default attribute value");'
+p577
+ssS'media/video-size.html'
+p578
+(dp579
+g8
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p580
+ssS'media/video-delay-load-event.html'
+p581
+(dp582
+g8
+S"Test the document's load event is delayed until a movie's meta data is available."
+p583
+sg10
+(lp584
+(dp585
+g100
+I01
+sg17
+(lp586
+S'BUGWK64003'
+p587
+asg15
+S' Started around WebKit r90233:r90242'
+p588
+sg76
+I01
+sg49
+I01
+sg321
+I01
+sassS'media/fallback.html'
+p589
+(dp590
+g8
+S'Test that fallback content is not rendered'
+p591
+ssS'fast/layers/video-layer.html'
+p592
+(dp593
+g8
+S'Video element gets layer'
+p594
+ssS'media/controls-strict.html'
+p595
+(dp596
+g8
+S'Drawing the controls in strict mode.'
+p597
+ssS'media/remove-from-document.html'
+p598
+(dp599
+g8
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p600
+ssS'http/tests/media/remove-while-loading.html'
+p601
+(dp602
+g8
+S'Test that removing a media element from the tree while loading does not crash.'
+p603
+ssS'media/video-controls-transformed.html'
+p604
+(dp605
+g8
+S'This test only runs in DRT!'
+p606
+ssS'compositing/video/video-poster.html'
+p607
+(dp608
+g8
+S'Video with poster'
+p609
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p610
+(dp611
+g8
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p612
+ssS'media/video-display-toggle.html'
+p613
+(dp614
+g8
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p615
+ssS'media/video-seek-no-src-exception.html'
+p616
+(dp617
+g8
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p618
+ssS'media/audio-constructor-src.html'
+p619
+(dp620
+g8
+S'Test that Audio("url") constructor loads the specified resource.'
+p621
+ssS'compositing/geometry/clipped-video-controller.html'
+p622
+(dp623
+g8
+S'Clipped Video'
+p624
+ssS'media/video-preload.html'
+p625
+(dp626
+g8
+S"Test to see if media loads automatically when 'preload' is specified."
+p627
+ssS'http/tests/media/video-load-twice.html'
+p628
+(dp629
+g8
+g69
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p630
+(dp631
+g8
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p632
+ssS'media/video-seek-past-end-playing.html'
+p633
+(dp634
+g8
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p635
+ssS'media/video-source.html'
+p636
+(dp637
+g8
+g69
+ssS'http/tests/media/reload-after-dialog.html'
+p638
+(dp639
+g8
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p640
+ssS'media/media-constants.html'
+p641
+(dp642
+g8
+S'Test HTMLMediaElement and MediaError constants.'
+p643
+ssS'media/video-volume.html'
+p644
+(dp645
+g8
+S"Test 'volume' attribute"
+p646
+ssS'media/video-src-source.html'
+p647
+(dp648
+g8
+g69
+ssS'http/tests/appcache/video.html'
+p649
+(dp650
+g8
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p651
+ssg53
+g54
+sg67
+g68
+sS'media/video-canvas-source.html'
+p652
+(dp653
+g8
+S'Drawing to canvas using video with source element does not taint canvas'
+p654
+ssS'media/video-controls-no-scripting.html'
+p655
+(dp656
+g8
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p657
+ssS'media/video-poster-scale.html'
+p658
+(dp659
+g8
+S"'poster' aspect ratio test"
+p660
+ssS'media/video-seek-by-small-increment.html'
+p661
+(dp662
+g8
+S'Test seeking by very small increments.'
+p663
+ssS'media/video-controls-with-mutation-event-handler.html'
+p664
+(dp665
+g8
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p666
+ssS'media/video-zoom-controls.html'
+p667
+(dp668
+g8
+S'Zoomed video with controls.'
+p669
+ssS'media/video-loop.html'
+p670
+(dp671
+g8
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p672
+sg10
+(lp673
+(dp674
+S'WIN'
+p675
+I01
+sg49
+I01
+sg17
+(lp676
+S'BUGCR59415'
+p677
+asg15
+S' BUGCR59415 : cannot repro the flakiness'
+p678
+sg14
+I01
+sg100
+I01
+sassS'http/tests/media/video-play-stall.html'
+p679
+(dp680
+g8
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p681
+sg10
+(lp682
+(dp683
+g100
+I01
+sg17
+(lp684
+S'BUGCR73609'
+p685
+asg15
+S' canplaythrough event is sent too early.'
+p686
+sassS'media/video-seeking.html'
+p687
+(dp688
+g8
+S'Test that seeking attribute is true immediately after a seek,'
+p689
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p690
+(dp691
+g8
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p692
+ssS'media/controls-after-reload.html'
+p693
+(dp694
+g8
+S'Making sure the controller looks ok after a second load().'
+p695
+ssg161
+g162
+sS'media/video-load-networkState.html'
+p696
+(dp697
+g8
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p698
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p699
+(dp700
+g8
+g69
+ssS'compositing/reflections/load-video-in-reflection.html'
+p701
+(dp702
+g8
+S'You should see a reflected video below, rather than the red video background.'
+p703
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p704
+(dp705
+g8
+S'Video overlay'
+p706
+ssS'media/video-controls-rendering.html'
+p707
+(dp708
+g8
+S'Test controls placement.'
+p709
+sg10
+(lp710
+(dp711
+g72
+I01
+sS'LINUX'
+p712
+I01
+sg17
+(lp713
+S'BUGCR74102'
+p714
+asg15
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p715
+sg49
+I01
+sg77
+I01
+sa(dp716
+g44
+I01
+sg72
+I01
+sg17
+(lp717
+S'BUGCR86714'
+p718
+asg15
+g324
+sg76
+I01
+sg77
+I01
+sassS'http/tests/media/video-served-as-text.html'
+p719
+(dp720
+g8
+S"media file served as 'text/plain'"
+p721
+ssS'media/video-pause-empty-events.html'
+p722
+(dp723
+g8
+S'Test that pause() from EMPTY network state triggers load()'
+p724
+ssS'media/video-poster-delayed.html'
+p725
+(dp726
+g8
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p727
+ssS'media/media-load-event.html'
+p728
+(dp729
+g8
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p730
+ssS'http/tests/media/video-error-abort.html'
+p731
+(dp732
+g8
+S"'abort' event test"
+p733
+ssS'media/video-volume-slider.html'
+p734
+(dp735
+g8
+S'Test rendering of volume slider of video tag'
+p736
+ssS'media/video-seek-past-end-paused.html'
+p737
+(dp738
+g8
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p739
+ssS'http/tests/media/video-cookie.html'
+p740
+(dp741
+g8
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p742
+ssS'media/remove-from-document-before-load.html'
+p743
+(dp744
+g8
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p745
+ssg210
+g211
+sS'media/video-duration-known-after-eos.html'
+p746
+(dp747
+g8
+S'Tests that duration is known after playback ended.'
+p748
+ssg213
+g214
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p749
+(dp750
+g8
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p751
+ssS'media/video-timeupdate-during-playback.html'
+p752
+(dp753
+g8
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p754
+ssS'media/video-single-valid-source.html'
+p755
+(dp756
+g8
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p757
+ssS'media/video-src-invalid-remove.html'
+p758
+(dp759
+g8
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p760
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p761
+(dp762
+g8
+S"This test passes if it doesn't alert failure."
+p763
+ssg197
+g198
+sS'media/video-load-readyState.html'
+p764
+(dp765
+g8
+g69
+sssS'nonskip'
+p766
+(dp767
+g403
+g404
+sg349
+g350
+sg679
+g680
+sg246
+g247
+sg536
+g537
+sg670
+g671
+sg707
+g708
+sg581
+g582
+sg367
+g368
+sg316
+g317
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/result/2011-08-19-21 b/chromium/media/tools/layout_tests/result/2011-08-19-21
new file mode 100644
index 00000000000..9c33ce2ae14
--- /dev/null
+++ b/chromium/media/tools/layout_tests/result/2011-08-19-21
@@ -0,0 +1,1883 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/video-does-not-loop.html'
+p6
+(dp7
+S'te_info'
+p8
+(lp9
+(dp10
+S'SKIP'
+p11
+I01
+sS'WONTFIX'
+p12
+I01
+sS'Comments'
+p13
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p14
+sS'TIMEOUT'
+p15
+I01
+sasS'desc'
+p16
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p17
+ssS'media/audio-delete-while-step-button-clicked.html'
+p18
+(dp19
+g8
+(lp20
+(dp21
+S'FAIL'
+p22
+I01
+sg11
+I01
+sS'Bugs'
+p23
+(lp24
+S'BUGCR25375'
+p25
+aS'BUGCR59399'
+p26
+asg13
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p27
+sasg16
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p28
+ssS'media/restore-from-page-cache.html'
+p29
+(dp30
+g8
+(lp31
+(dp32
+g11
+I01
+sg12
+I01
+sg13
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p33
+sg15
+I01
+sg23
+(lp34
+S'BUGCR19635'
+p35
+asasg16
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p36
+ssS'media/context-menu-actions.html'
+p37
+(dp38
+g8
+(lp39
+(dp40
+S'CRASH'
+p41
+I01
+sg11
+I01
+sg23
+(lp42
+S'BUGCR59665'
+p43
+aS'BUGWK45021'
+p44
+asg13
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p45
+sg15
+I01
+sS'PASS'
+p46
+I01
+sasg16
+S'Test the various actions available in the HTML5 media element context-menu.'
+p47
+ssS'media/track/track-webvtt-tc005-headercomment.html'
+p48
+(dp49
+g8
+(lp50
+(dp51
+g11
+I01
+sg13
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p52
+sg15
+I01
+sg23
+(lp53
+S'BUGWK43668'
+p54
+asasg16
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p55
+ssS'http/tests/media/video-cross-site.html'
+p56
+(dp57
+g8
+(lp58
+(dp59
+g11
+I01
+sg13
+S' QuickTime reference movies not supported.'
+p60
+sg15
+I01
+sg46
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'media file redirects to another site'
+p61
+ssS'media/audio-data-url.html'
+p62
+(dp63
+g8
+(lp64
+(dp65
+g11
+I01
+sg23
+(lp66
+S'BUGCR16779'
+p67
+asg13
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that audio element can use a data: url'
+p69
+ssS'media/video-canvas-alpha.html'
+p70
+(dp71
+g8
+(lp72
+(dp73
+g11
+I01
+sS'IMAGE'
+p74
+I01
+sg23
+(lp75
+S'BUGCR74979'
+p76
+asg13
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p77
+sS'MAC'
+p78
+I01
+sS'GPU'
+p79
+I01
+sasg16
+S'UNKNOWN'
+p80
+ssS'media/video-can-play-type.html'
+p81
+(dp82
+g8
+(lp83
+(dp84
+g11
+I01
+sg23
+(lp85
+S'BUGCR16779'
+p86
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p87
+ssS'media/media-captions.html'
+p88
+(dp89
+g8
+(lp90
+(dp91
+g11
+I01
+sg13
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p92
+sg15
+I01
+sg23
+(lp93
+S'BUGCR28301'
+p94
+asasg16
+S'Test media element close caption API.'
+p95
+ssS'media/video-size-intrinsic-scale.html'
+p96
+(dp97
+g8
+(lp98
+(dp99
+g11
+I01
+sg23
+(lp100
+S'BUGCR16779'
+p101
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'&lt;video&gt; element intrinsic size test'
+p102
+ssS'media/track/track-webvtt-tc011-blanklines.html'
+p103
+(dp104
+g8
+g50
+sg16
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p105
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p106
+(dp107
+g8
+g50
+sg16
+S'Tests cues that are temporally out of order (we allow this).'
+p108
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p109
+(dp110
+g8
+g50
+sg16
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p111
+ssS'media/media-can-play-mpeg-audio.html'
+p112
+(dp113
+g8
+(lp114
+(dp115
+g11
+I01
+sg12
+I01
+sg23
+(lp116
+S'BUGCR16779'
+p117
+asg13
+g68
+sS'TEXT'
+p118
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p119
+ssS'media/audio-mpeg4-supported.html'
+p120
+(dp121
+g8
+(lp122
+(dp123
+g11
+I01
+sg23
+(lp124
+S'BUGCR16779'
+p125
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that the audio element supports M4A files.'
+p126
+ssS'media/track/track-webvtt-tc004-magicheader.html'
+p127
+(dp128
+g8
+g50
+sg16
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p129
+ssS'media/media-fullscreen-not-in-document.html'
+p130
+(dp131
+g8
+(lp132
+(dp133
+g11
+I01
+sg13
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p134
+sg15
+I01
+sg23
+(lp135
+S'BUGCR16735'
+p136
+asasg16
+S'Test media element fullscreen API when an element is not in the DOM.'
+p137
+ssS'media/audio-mpeg-supported.html'
+p138
+(dp139
+g8
+(lp140
+(dp141
+g11
+I01
+sg23
+(lp142
+S'BUGCR16779'
+p143
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that the audio element supports MPEG files.'
+p144
+ssS'media/track/track-webvtt-tc003-newlines.html'
+p145
+(dp146
+g8
+g50
+sg16
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p147
+ssS'media/video-document-types.html'
+p148
+(dp149
+g8
+(lp150
+(dp151
+g11
+I01
+sg23
+(lp152
+S'BUGCR16779'
+p153
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p154
+ssS'media/track/track-webvtt-tc002-bom.html'
+p155
+(dp156
+g8
+g50
+sg16
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p157
+ssS'media/media-fullscreen-inline.html'
+p158
+(dp159
+g8
+(lp160
+(dp161
+g11
+I01
+sg13
+g134
+sg15
+I01
+sg23
+(lp162
+S'BUGCR16735'
+p163
+asasg16
+S'Test media element fullscreen API when an element is in the DOM.'
+p164
+ssS'media/track/track-webvtt-tc000-empty.html'
+p165
+(dp166
+g8
+g50
+sg16
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p167
+ssS'media/media-can-play-mpeg4-video.html'
+p168
+(dp169
+g8
+(lp170
+(dp171
+g11
+I01
+sg12
+I01
+sg23
+(lp172
+S'BUGWK45102'
+p173
+asg13
+g68
+sg118
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p174
+ssS'compositing/video/video-background-color.html'
+p175
+(dp176
+g8
+(lp177
+(dp178
+g22
+I01
+sg11
+I01
+sg12
+I01
+sg23
+(lp179
+S'BUGWK55519'
+p180
+asg13
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p181
+sasg16
+S'Video with background color'
+p182
+ssS'media/track/track-webvtt-tc010-notimings.html'
+p183
+(dp184
+g8
+g50
+sg16
+S'Tests cue without timings are ignored.'
+p185
+ssS'media/video-timeupdate-reverse-play.html'
+p186
+(dp187
+g8
+(lp188
+(dp189
+g11
+I01
+sg13
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p190
+sg15
+I01
+sg23
+(lp191
+S'BUGCR33099'
+p192
+asasg16
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p193
+ssS'http/tests/media/video-buffered.html'
+p194
+(dp195
+g8
+(lp196
+(dp197
+g11
+I01
+sg23
+(lp198
+S'BUGCR49165'
+p199
+asg13
+S' video.buffered multiple TimeRanges support.'
+p200
+sg46
+I01
+sasg16
+g80
+ssS'media/track/track-webvtt-tc001-utf8.html'
+p201
+(dp202
+g8
+g50
+sg16
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p203
+ssS'media/track/track-webvtt-tc013-settings.html'
+p204
+(dp205
+g8
+g50
+sg16
+S'Tests WebVTT settings.'
+p206
+ssS'media/track/track-webvtt-tc007-cuenoid.html'
+p207
+(dp208
+g8
+g50
+sg16
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p209
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p210
+(dp211
+g8
+g50
+sg16
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p212
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p213
+(dp214
+g8
+g50
+sg16
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p215
+ssS'media/video-element-other-namespace-crash.html'
+p216
+(dp217
+g8
+(lp218
+(dp219
+g11
+I01
+sg12
+I01
+sg13
+g68
+sg15
+I01
+sg23
+(lp220
+S'BUGCR68289'
+p221
+asasg16
+g80
+ssS'media/video-reverse-play-duration.html'
+p222
+(dp223
+g8
+(lp224
+(dp225
+g11
+I01
+sg13
+g190
+sg15
+I01
+sg23
+(lp226
+S'BUGCR33099'
+p227
+asasg16
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p228
+sssS'whole'
+p229
+(dp230
+S'media/video-source-type.html'
+p231
+(dp232
+g16
+S'&lt;source&gt; @type attribute'
+p233
+ssS'media/media-startTime.html'
+p234
+(dp235
+g16
+S"Test the, so far unused, 'startTime' attribute."
+p236
+ssS'media/video-src-set.html'
+p237
+(dp238
+g16
+S'Test that setting src attribute triggers load'
+p239
+ssg18
+g19
+sS'media/video-played-ranges-1.html'
+p240
+(dp241
+g16
+S"Test of the media element 'played' attribute, ranges part 1."
+p242
+ssS'http/tests/media/video-play-stall-seek.html'
+p243
+(dp244
+g8
+(lp245
+(dp246
+g13
+S' Timing out.'
+p247
+sg15
+I01
+sg23
+(lp248
+S'BUGCR78376'
+p249
+asasg16
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p250
+ssg62
+g63
+sg81
+g82
+sg88
+g89
+sS'media/controls-after-reload.html'
+p251
+(dp252
+g16
+S'Making sure the controller looks ok after a second load().'
+p253
+ssS'http/tests/media/video-referer.html'
+p254
+(dp255
+g16
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p256
+ssS'media/video-source-removed.html'
+p257
+(dp258
+g16
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p259
+ssS'media/unsupported-tracks.html'
+p260
+(dp261
+g16
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p262
+ssg120
+g121
+sS'media/audio-no-installed-engines.html'
+p263
+(dp264
+g16
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p265
+ssg130
+g131
+sS'media/video-width-height.html'
+p266
+(dp267
+g16
+g80
+ssS'media/media-blocked-by-willsendrequest.html'
+p268
+(dp269
+g16
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p270
+ssS'media/video-error-does-not-exist.html'
+p271
+(dp272
+g16
+S'Test that the media element is in correct state after load fails.'
+p273
+ssS'media/video-play-pause-events.html'
+p274
+(dp275
+g16
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p276
+ssS'media/video-display-none-crash.html'
+p277
+(dp278
+g16
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p279
+ssS'media/video-src-plus-source.html'
+p280
+(dp281
+g16
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p282
+ssS'media/video-source-none-supported.html'
+p283
+(dp284
+g16
+S'no usable &lt;source&gt; test'
+p285
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p286
+(dp287
+g16
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p288
+ssg6
+g7
+sS'media/video-src.html'
+p289
+(dp290
+g16
+g80
+ssg175
+g176
+sS'media/video-src-invalid-poster.html'
+p291
+(dp292
+g16
+g80
+ssS'media/video-source-inserted.html'
+p293
+(dp294
+g16
+S'networkState after inserting &lt;source&gt; test'
+p295
+ssS'media/media-can-play-octet-stream.html'
+p296
+(dp297
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p298
+ssS'media/constructors.html'
+p299
+(dp300
+g16
+S'Test that media constructors behave consistently.'
+p301
+ssS'media/video-source-media.html'
+p302
+(dp303
+g16
+g80
+ssg194
+g195
+sS'media/video-aspect-ratio.html'
+p304
+(dp305
+g16
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p306
+ssg201
+g202
+sS'media/video-source-type-params.html'
+p307
+(dp308
+g16
+g80
+ssS'fast/canvas/webgl/context-lost.html'
+p309
+(dp310
+g16
+S'debug("Test valid context");'
+p311
+ssS'media/media-can-play-wav-audio.html'
+p312
+(dp313
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p314
+ssS'media/video-source-error.html'
+p315
+(dp316
+g8
+(lp317
+(dp318
+S'DEBUG'
+p319
+I01
+sg118
+I01
+sg23
+(lp320
+S'BUGWK66310'
+p321
+asg13
+S''
+p322
+sg46
+I01
+sasg16
+S'&lt;video&gt; and &lt;source&gt; error test'
+p323
+ssS'media/video-no-audio.html'
+p324
+(dp325
+g16
+S'Movie with no audio track. The volume button should not render.'
+p326
+ssS'media/svg-as-image-with-media-blocked.html'
+p327
+(dp328
+g16
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p329
+ssS'media/video-transformed.html'
+p330
+(dp331
+g16
+S'Test painting of transformed video'
+p332
+ssg207
+g208
+sg213
+g214
+sS'media/video-click-dblckick-standalone.html'
+p333
+(dp334
+g16
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p335
+ssS'media/video-pause-immediately.html'
+p336
+(dp337
+g16
+S'Test that pausing the media element has an immediate effect on the clock.'
+p338
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p339
+(dp340
+g16
+g80
+ssg222
+g223
+sS'http/tests/security/local-video-src-from-remote.html'
+p341
+(dp342
+g16
+S'This test only works in DRT'
+p343
+ssS'media/media-document-audio-repaint.html'
+p344
+(dp345
+g8
+(lp346
+(dp347
+g118
+I01
+sg74
+I01
+sg23
+(lp348
+S'BUGCR75354'
+p349
+aS'BUGWK55718'
+p350
+asg13
+S' This test needs completely new baselines.'
+p351
+sS'IMAGE+TEXT'
+p352
+I01
+sasg16
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p353
+ssS'media/video-controls-in-media-document.html'
+p354
+(dp355
+g16
+g80
+ssS'media/remove-from-document-no-load.html'
+p356
+(dp357
+g16
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p358
+ssS'media/video-currentTime.html'
+p359
+(dp360
+g16
+g80
+ssS'media/video-frame-accurate-seek.html'
+p361
+(dp362
+g8
+(lp363
+(dp364
+g74
+I01
+sg23
+(lp365
+S'BUGCR72223'
+p366
+asg13
+g322
+sg46
+I01
+sasg16
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p367
+ssg29
+g30
+sg37
+g38
+sS'media/video-load-networkState.html'
+p368
+(dp369
+g16
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p370
+ssg48
+g49
+sS'media/controls-css-overload.html'
+p371
+(dp372
+g16
+S"Testing that overloading some controls doesn't crash the browser"
+p373
+ssS'media/video-display-aspect-ratio.html'
+p374
+(dp375
+g16
+g80
+ssS'media/video-currentTime-set.html'
+p376
+(dp377
+g16
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p378
+ssS'media/media-blocked-by-beforeload.html'
+p379
+(dp380
+g8
+(lp381
+(dp382
+g118
+I01
+sg23
+(lp383
+S'BUGWK66310'
+p384
+asg13
+g322
+sg46
+I01
+sasg16
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p385
+ssg106
+g107
+sS'media/video-controls-visible-audio-only.html'
+p386
+(dp387
+g16
+S'This test only runs in DRT!'
+p388
+ssS'http/tests/media/video-play-progress.html'
+p389
+(dp390
+g16
+S'Test that at least one progress event is fired after starting to load the video.'
+p391
+ssg112
+g113
+sS'media/video-source-moved.html'
+p392
+(dp393
+g16
+S'moving &lt;source&gt; element test'
+p394
+ssS'http/tests/security/local-video-source-from-remote.html'
+p395
+(dp396
+g16
+S'This test only behaves correctly in DRT'
+p397
+ssS'media/video-src-none.html'
+p398
+(dp399
+g16
+g80
+ssS'media/video-controls-zoomed.html'
+p400
+(dp401
+g16
+S'This test only runs in DRT!'
+p402
+ssS'media/video-controls.html'
+p403
+(dp404
+g16
+S"Test 'controls' attribute"
+p405
+ssS'media/controls-without-preload.html'
+p406
+(dp407
+g16
+S'The controls should not depend on preload value.'
+p408
+ssS'media/video-played-collapse.html'
+p409
+(dp410
+g16
+S"Test of the media element 'played' attribute"
+p411
+ssS'compositing/self-painting-layers.html'
+p412
+(dp413
+g16
+S'Self painting layers'
+p414
+ssS'media/audio-controls-do-not-fade-out.html'
+p415
+(dp416
+g16
+S'This tests that audio controls do not fade out when the audio is playing.'
+p417
+ssg158
+g159
+sS'compositing/geometry/video-opacity-overlay.html'
+p418
+(dp419
+g16
+S'Video overlay'
+p420
+ssS'media/video-source-error-no-candidate.html'
+p421
+(dp422
+g16
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p423
+ssS'media/audio-constructor.html'
+p424
+(dp425
+g16
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p426
+ssS'media/controls-styling.html'
+p427
+(dp428
+g16
+S'The look of the controls should not change.'
+p429
+ssS'media/event-attributes.html'
+p430
+(dp431
+g16
+g80
+ssg183
+g184
+sg186
+g187
+sS'http/tests/media/text-served-as-text.html'
+p432
+(dp433
+g16
+S"text file served as 'text/plain'"
+p434
+ssS'http/tests/media/video-cancel-load.html'
+p435
+(dp436
+g16
+S'Cancel loading a video file and access its properties afterwards.'
+p437
+ssS'media/unsupported-rtsp.html'
+p438
+(dp439
+g16
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p440
+ssS'media/media-controls-clone.html'
+p441
+(dp442
+g16
+S'<video controls id=v></video><audio controls id=a></audio>'
+p443
+ssS'media/broken-video.html'
+p444
+(dp445
+g16
+S'Test that QuickTime file with broken content generates an error.'
+p446
+ssS'media/video-plays-past-end-of-test.html'
+p447
+(dp448
+g16
+g80
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p449
+(dp450
+g16
+S'WebGL Origin Restrictions Conformance Tests'
+p451
+ssS'media/video-replaces-poster.html'
+p452
+(dp453
+g16
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p454
+ssS'media/video-autoplay.html'
+p455
+(dp456
+g16
+g80
+ssS'media/video-set-rate-from-pause.html'
+p457
+(dp458
+g16
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p459
+ssS'media/video-src-remove.html'
+p460
+(dp461
+g16
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p462
+ssS'media/csp-blocks-video.html'
+p463
+(dp464
+g16
+S"This test passes if it doesn't alert failure."
+p465
+ssS'media/controls-drag-timebar.html'
+p466
+(dp467
+g16
+S'Test that dragging the timebar thumb causes seeks.'
+p468
+ssS'media/audio-constructor-preload.html'
+p469
+(dp470
+g16
+S"Test that Audio() sets 'preload' attribute."
+p471
+ssS'media/video-poster-delayed.html'
+p472
+(dp473
+g16
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p474
+ssS'media/adopt-node-crash.html'
+p475
+(dp476
+g16
+S"Tests that we don't crash when moving a video element to a new document."
+p477
+ssS'media/video-playbackrate.html'
+p478
+(dp479
+g16
+S'test playbackRate and defaultPlaybackRate'
+p480
+ssS'media/video-muted.html'
+p481
+(dp482
+g16
+S"Test 'muted' attribute"
+p483
+ssS'media/video-src-change.html'
+p484
+(dp485
+g16
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p486
+ssS'compositing/overflow/overflow-compositing-descendant.html'
+p487
+(dp488
+g16
+S'You should see a green box under the video. If you see red, the test failed.'
+p489
+ssg216
+g217
+sS'media/video-play-pause-exception.html'
+p490
+(dp491
+g16
+S'Video has no src. Test that the playing event is not dispatched.'
+p492
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p493
+(dp494
+g16
+g80
+ssS'media/audio-play-event.html'
+p495
+(dp496
+g16
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p497
+ssS'media/before-load-member-access.html'
+p498
+(dp499
+g16
+S'Test that accessing member of a non loaded video works.'
+p500
+ssS'media/video-dom-src.html'
+p501
+(dp502
+g16
+g80
+ssS'media/audio-repaint.html'
+p503
+(dp504
+g16
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p505
+ssS'media/audio-controls-rendering.html'
+p506
+(dp507
+g16
+S'Test controls placement.'
+p508
+ssg204
+g205
+sS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p509
+(dp510
+g16
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p511
+ssS'media/invalid-media-url-crash.html'
+p512
+(dp513
+g16
+S'Tests that invalid media src url does not result in crash.'
+p514
+ssS'media/video-empty-source.html'
+p515
+(dp516
+g16
+S'Slider drawing with no source. The controls should render correctly.'
+p517
+ssg96
+g97
+sS'media/video-poster.html'
+p518
+(dp519
+g16
+S'Test &lt;video&gt; element with and without a poster.'
+p520
+ssS'media/media-document-audio-size.html'
+p521
+(dp522
+g16
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p523
+ssS'media/video-zoom.html'
+p524
+(dp525
+g8
+(lp526
+(dp527
+g41
+I01
+sg74
+I01
+sg23
+(lp528
+S'BUGCR86714'
+p529
+asg13
+g322
+sg78
+I01
+sg79
+I01
+sasg16
+S'150% zoom, with width and height attributes'
+p530
+ssg103
+g104
+sS'http/tests/appcache/video.html'
+p531
+(dp532
+g16
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p533
+ssS'media/video-dom-autoplay.html'
+p534
+(dp535
+g16
+g80
+ssS'media/media-ended.html'
+p536
+(dp537
+g16
+S'<b>Test ended by:</b>'
+p538
+ssS'media/video-no-autoplay.html'
+p539
+(dp540
+g16
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p541
+ssg138
+g139
+sS'media/video-append-source.html'
+p542
+(dp543
+g16
+g80
+ssg145
+g146
+sS'http/tests/media/pdf-served-as-pdf.html'
+p544
+(dp545
+g16
+S"PDF file served as 'application/pdf'"
+p546
+ssS'media/video-play-empty-events.html'
+p547
+(dp548
+g16
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p549
+ssg155
+g156
+sS'media/audio-only-video-intrinsic-size.html'
+p550
+(dp551
+g16
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p552
+ssg148
+g149
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p553
+(dp554
+g16
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p555
+ssS'media/media-can-play-ogg.html'
+p556
+(dp557
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p558
+ssg127
+g128
+sg165
+g166
+sS'media/video-currentTime-set2.html'
+p559
+(dp560
+g16
+g80
+ssS'media/video-seekable.html'
+p561
+(dp562
+g16
+g80
+ssS'fast/dom/beforeload/video-before-load.html'
+p563
+(dp564
+g16
+g80
+ssS'media/video-played-reset.html'
+p565
+(dp566
+g16
+S"Test of the media element 'played' attribute"
+p567
+ssS'compositing/self-painting-layers2.html'
+p568
+(dp569
+g16
+S'This test should not assert in debug builds.'
+p570
+ssS'media/controls-right-click-on-timebar.html'
+p571
+(dp572
+g16
+S'Test that right clicking on the timebar does not cause a seek.'
+p573
+ssS'media/video-dom-preload.html'
+p574
+(dp575
+g16
+S'consoleWrite("++ Test default attribute value");'
+p576
+ssS'media/video-size.html'
+p577
+(dp578
+g16
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p579
+ssS'media/video-load-preload-none.html'
+p580
+(dp581
+g16
+S'Test that an explicit load() to a media element whose preload is set to "none" still loads the video.'
+p582
+ssS'media/video-delay-load-event.html'
+p583
+(dp584
+g8
+(lp585
+(dp586
+g118
+I01
+sg23
+(lp587
+S'BUGWK64003'
+p588
+asg13
+S' Started around WebKit r90233:r90242'
+p589
+sg78
+I01
+sg46
+I01
+sg319
+I01
+sasg16
+S"Test the document's load event is delayed until a movie's meta data is available."
+p590
+ssS'media/fallback.html'
+p591
+(dp592
+g16
+S'Test that fallback content is not rendered'
+p593
+ssS'media/video-layer-crash.html'
+p594
+(dp595
+g16
+S'Test dynamic removal of transformed and reflected video'
+p596
+ssS'fast/layers/video-layer.html'
+p597
+(dp598
+g16
+S'Video element gets layer'
+p599
+ssS'media/controls-strict.html'
+p600
+(dp601
+g16
+S'Drawing the controls in strict mode.'
+p602
+ssS'media/remove-from-document.html'
+p603
+(dp604
+g16
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p605
+ssS'http/tests/media/remove-while-loading.html'
+p606
+(dp607
+g16
+S'Test that removing a media element from the tree while loading does not crash.'
+p608
+ssS'media/video-controls-transformed.html'
+p609
+(dp610
+g16
+S'This test only runs in DRT!'
+p611
+ssS'compositing/video/video-poster.html'
+p612
+(dp613
+g16
+S'Video with poster'
+p614
+ssS'media/video-display-toggle.html'
+p615
+(dp616
+g16
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p617
+ssS'media/video-seek-no-src-exception.html'
+p618
+(dp619
+g16
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p620
+ssS'media/audio-constructor-src.html'
+p621
+(dp622
+g16
+S'Test that Audio("url") constructor loads the specified resource.'
+p623
+ssS'compositing/geometry/clipped-video-controller.html'
+p624
+(dp625
+g16
+S'Clipped Video'
+p626
+ssS'media/video-preload.html'
+p627
+(dp628
+g16
+S"Test to see if media loads automatically when 'preload' is specified."
+p629
+ssS'http/tests/media/video-load-twice.html'
+p630
+(dp631
+g16
+g80
+ssS'http/tests/media/video-cookie.html'
+p632
+(dp633
+g16
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p634
+ssS'media/video-source.html'
+p635
+(dp636
+g16
+g80
+ssS'media/video-seek-past-end-playing.html'
+p637
+(dp638
+g16
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p639
+ssS'media/video-currentTime-delay.html'
+p640
+(dp641
+g16
+S'Test a delay in playing the movie results in a canPlay event.'
+p642
+ssS'http/tests/media/reload-after-dialog.html'
+p643
+(dp644
+g16
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p645
+ssS'media/media-constants.html'
+p646
+(dp647
+g16
+S'Test HTMLMediaElement and MediaError constants.'
+p648
+ssS'media/video-volume.html'
+p649
+(dp650
+g16
+S"Test 'volume' attribute"
+p651
+ssS'media/video-src-source.html'
+p652
+(dp653
+g16
+g80
+ssS'media/video-buffered.html'
+p654
+(dp655
+g16
+g80
+ssg56
+g57
+sg70
+g71
+sS'media/video-canvas-source.html'
+p656
+(dp657
+g16
+S'Drawing to canvas using video with source element does not taint canvas'
+p658
+ssS'media/video-controls-no-scripting.html'
+p659
+(dp660
+g16
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p661
+ssS'media/video-poster-scale.html'
+p662
+(dp663
+g16
+S"'poster' aspect ratio test"
+p664
+ssS'media/video-seek-by-small-increment.html'
+p665
+(dp666
+g16
+S'Test seeking by very small increments.'
+p667
+ssS'media/video-controls-with-mutation-event-handler.html'
+p668
+(dp669
+g16
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p670
+ssS'media/video-zoom-controls.html'
+p671
+(dp672
+g16
+S'Zoomed video with controls.'
+p673
+ssS'media/video-loop.html'
+p674
+(dp675
+g8
+(lp676
+(dp677
+S'WIN'
+p678
+I01
+sg46
+I01
+sg23
+(lp679
+S'BUGCR59415'
+p680
+asg13
+S' BUGCR59415 : cannot repro the flakiness'
+p681
+sg15
+I01
+sg118
+I01
+sasg16
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p682
+ssS'http/tests/media/video-play-stall.html'
+p683
+(dp684
+g8
+(lp685
+(dp686
+g118
+I01
+sg23
+(lp687
+S'BUGCR73609'
+p688
+asg13
+S' canplaythrough event is sent too early.'
+p689
+sasg16
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p690
+ssS'media/video-seeking.html'
+p691
+(dp692
+g16
+S'Test that seeking attribute is true immediately after a seek,'
+p693
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p694
+(dp695
+g16
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p696
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p697
+(dp698
+g16
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p699
+ssg168
+g169
+sS'media/media-controls-clone-crash.html'
+p700
+(dp701
+g16
+S'Test passes if it does not crash.'
+p702
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p703
+(dp704
+g16
+g80
+ssS'compositing/reflections/load-video-in-reflection.html'
+p705
+(dp706
+g16
+S'You should see a reflected video below, rather than the red video background.'
+p707
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p708
+(dp709
+g16
+S'Video overlay'
+p710
+ssS'media/video-controls-rendering.html'
+p711
+(dp712
+g8
+(lp713
+(dp714
+g74
+I01
+sS'LINUX'
+p715
+I01
+sg23
+(lp716
+S'BUGCR74102'
+p717
+asg13
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p718
+sg46
+I01
+sg79
+I01
+sa(dp719
+g41
+I01
+sg74
+I01
+sg23
+(lp720
+S'BUGCR86714'
+p721
+asg13
+g322
+sg78
+I01
+sg79
+I01
+sasg16
+S'Test controls placement.'
+p722
+ssS'http/tests/media/video-served-as-text.html'
+p723
+(dp724
+g16
+S"media file served as 'text/plain'"
+p725
+ssS'media/video-pause-empty-events.html'
+p726
+(dp727
+g16
+S'Test that pause() from EMPTY network state triggers load()'
+p728
+ssS'media/media-load-event.html'
+p729
+(dp730
+g16
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p731
+ssS'http/tests/media/video-error-abort.html'
+p732
+(dp733
+g16
+S"'abort' event test"
+p734
+ssS'media/video-volume-slider.html'
+p735
+(dp736
+g16
+S'Test rendering of volume slider of video tag'
+p737
+ssS'media/video-seek-past-end-paused.html'
+p738
+(dp739
+g16
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p740
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p741
+(dp742
+g16
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p743
+ssS'media/remove-from-document-before-load.html'
+p744
+(dp745
+g16
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p746
+ssg210
+g211
+sS'media/video-duration-known-after-eos.html'
+p747
+(dp748
+g16
+S'Tests that duration is known after playback ended.'
+p749
+ssg109
+g110
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p750
+(dp751
+g16
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p752
+ssS'media/video-timeupdate-during-playback.html'
+p753
+(dp754
+g16
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p755
+ssS'media/video-single-valid-source.html'
+p756
+(dp757
+g16
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p758
+ssS'media/video-src-invalid-remove.html'
+p759
+(dp760
+g16
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p761
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p762
+(dp763
+g16
+S"This test passes if it doesn't alert failure."
+p764
+ssS'media/video-load-readyState.html'
+p765
+(dp766
+g16
+g80
+sssS'nonskip'
+p767
+(dp768
+g344
+g345
+sg361
+g362
+sg711
+g712
+sg243
+g244
+sg524
+g525
+sg674
+g675
+sg683
+g684
+sg583
+g584
+sg379
+g380
+sg315
+g316
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/result/2011-09-11-18 b/chromium/media/tools/layout_tests/result/2011-09-11-18
new file mode 100644
index 00000000000..c3a55b433b0
--- /dev/null
+++ b/chromium/media/tools/layout_tests/result/2011-09-11-18
@@ -0,0 +1,2033 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/video-does-not-loop.html'
+p6
+(dp7
+S'te_info'
+p8
+(lp9
+(dp10
+S'SKIP'
+p11
+I01
+sS'WONTFIX'
+p12
+I01
+sS'Comments'
+p13
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p14
+sS'TIMEOUT'
+p15
+I01
+sasS'desc'
+p16
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p17
+ssS'media/track/track-webvtt-tc020-cue-size-align.html'
+p18
+(dp19
+g8
+(lp20
+(dp21
+g11
+I01
+sg13
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p22
+sg15
+I01
+sS'Bugs'
+p23
+(lp24
+S'BUGWK43668'
+p25
+asasg16
+S'Tests cue size and alignment from settings.'
+p26
+ssS'media/audio-delete-while-step-button-clicked.html'
+p27
+(dp28
+g8
+(lp29
+(dp30
+S'FAIL'
+p31
+I01
+sg11
+I01
+sg23
+(lp32
+S'BUGCR25375'
+p33
+aS'BUGCR59399'
+p34
+asg13
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p35
+sasg16
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p36
+ssS'media/restore-from-page-cache.html'
+p37
+(dp38
+g8
+(lp39
+(dp40
+g11
+I01
+sg12
+I01
+sg13
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p41
+sg15
+I01
+sasg16
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p42
+ssS'media/media-document-audio-repaint.html'
+p43
+(dp44
+g8
+(lp45
+(dp46
+S'IMAGE+TEXT'
+p47
+I01
+sg11
+I01
+sS'IMAGE'
+p48
+I01
+sg23
+(lp49
+S'BUGCR94918'
+p50
+asg13
+S' Skip test test since this test uses layoutTestController.display() that needs to be implemented for GPU'
+p51
+sS'TEXT'
+p52
+I01
+sS'GPU'
+p53
+I01
+sasg16
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p54
+ssS'media/media-can-play-mpeg4-video.html'
+p55
+(dp56
+g8
+(lp57
+(dp58
+g11
+I01
+sg12
+I01
+sg13
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p59
+sg52
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p60
+ssS'media/track/track-webvtt-tc007-cue-no-id.html'
+p61
+(dp62
+g8
+g20
+sg16
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p63
+ssS'http/tests/media/video-cross-site.html'
+p64
+(dp65
+g8
+(lp66
+(dp67
+g11
+I01
+sg13
+S' QuickTime reference movies not supported.'
+p68
+sg15
+I01
+sS'PASS'
+p69
+I01
+sg31
+I01
+sg12
+I01
+sasg16
+S'media file redirects to another site'
+p70
+ssS'media/audio-data-url.html'
+p71
+(dp72
+g8
+(lp73
+(dp74
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that audio element can use a data: url'
+p75
+ssS'media/video-canvas-alpha.html'
+p76
+(dp77
+g8
+(lp78
+(dp79
+g11
+I01
+sg48
+I01
+sg23
+(lp80
+S'BUGCR74979'
+p81
+asg13
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p82
+sS'MAC'
+p83
+I01
+sg53
+I01
+sasg16
+S'UNKNOWN'
+p84
+ssS'media/video-can-play-type.html'
+p85
+(dp86
+g8
+(lp87
+(dp88
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p89
+ssS'media/media-captions.html'
+p90
+(dp91
+g8
+(lp92
+(dp93
+g11
+I01
+sg13
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p94
+sg15
+I01
+sg23
+(lp95
+S'BUGCR28301'
+p96
+asasg16
+S'Test media element close caption API.'
+p97
+ssS'media/video-size-intrinsic-scale.html'
+p98
+(dp99
+g8
+(lp100
+(dp101
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'&lt;video&gt; element intrinsic size test'
+p102
+ssS'media/track/track-webvtt-tc004-magic-header.html'
+p103
+(dp104
+g8
+g20
+sg16
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p105
+ssS'media/media-can-play-mpeg-audio.html'
+p106
+(dp107
+g8
+(lp108
+(dp109
+g11
+I01
+sg12
+I01
+sg13
+g59
+sg52
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p110
+ssS'media/audio-mpeg4-supported.html'
+p111
+(dp112
+g8
+(lp113
+(dp114
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that the audio element supports M4A files.'
+p115
+ssS'media/media-fullscreen-not-in-document.html'
+p116
+(dp117
+g8
+(lp118
+(dp119
+g11
+I01
+sg13
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p120
+sg15
+I01
+sg23
+(lp121
+S'BUGCR16735'
+p122
+asasg16
+S'Test media element fullscreen API when an element is not in the DOM.'
+p123
+ssS'media/track/track-webvtt-tc014-alignment.html'
+p124
+(dp125
+g8
+g20
+sg16
+S'Tests cue alignment from settings.'
+p126
+ssS'media/track/track-webvtt-tc021-valign.html'
+p127
+(dp128
+g8
+g20
+sg16
+S'Tests cue vertical alignment (direction) from settings.'
+p129
+ssS'media/audio-mpeg-supported.html'
+p130
+(dp131
+g8
+(lp132
+(dp133
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that the audio element supports MPEG files.'
+p134
+ssS'media/track/track-webvtt-tc019-cue-size.html'
+p135
+(dp136
+g8
+g20
+sg16
+S'Tests cue size from settings.'
+p137
+ssS'media/track/track-webvtt-tc003-newlines.html'
+p138
+(dp139
+g8
+g20
+sg16
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p140
+ssS'media/video-document-types.html'
+p141
+(dp142
+g8
+(lp143
+(dp144
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p145
+ssS'media/track/track-webvtt-tc024-timestamp.html'
+p146
+(dp147
+g8
+g20
+sg16
+S'Tests cues with &lt;timestamps&gt; tags.'
+p148
+ssS'media/track/track-webvtt-tc008-timings-no-hours.html'
+p149
+(dp150
+g8
+g20
+sg16
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p151
+ssS'media/media-fullscreen-inline.html'
+p152
+(dp153
+g8
+(lp154
+(dp155
+g11
+I01
+sg13
+g120
+sg15
+I01
+sg23
+(lp156
+S'BUGCR16735'
+p157
+asasg16
+S'Test media element fullscreen API when an element is in the DOM.'
+p158
+ssS'media/track/track-webvtt-tc000-empty.html'
+p159
+(dp160
+g8
+g20
+sg16
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p161
+ssS'media/track/track-webvtt-tc018-align-text-line-position.html'
+p162
+(dp163
+g8
+g20
+sg16
+S'Tests cue alignment, line and text position from settings.'
+p164
+ssS'media/track/track-webvtt-tc002-bom.html'
+p165
+(dp166
+g8
+g20
+sg16
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p167
+ssS'compositing/video/video-background-color.html'
+p168
+(dp169
+g8
+(lp170
+(dp171
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p172
+sasg16
+S'Video with background color'
+p173
+ssS'media/track/track-webvtt-tc026-voice.html'
+p174
+(dp175
+g8
+g20
+sg16
+S'Tests cues with voice markup &lt;v&gt;.'
+p176
+ssS'media/track/track-webvtt-tc011-blank-lines.html'
+p177
+(dp178
+g8
+g20
+sg16
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p179
+ssS'media/context-menu-actions.html'
+p180
+(dp181
+g8
+(lp182
+(dp183
+S'CRASH'
+p184
+I01
+sg11
+I01
+sg23
+(lp185
+S'BUGCR59665'
+p186
+aS'BUGWK45021'
+p187
+asg13
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p188
+sg15
+I01
+sg69
+I01
+sasg16
+S'Test the various actions available in the HTML5 media element context-menu.'
+p189
+ssS'media/video-timeupdate-reverse-play.html'
+p190
+(dp191
+g8
+(lp192
+(dp193
+g11
+I01
+sg13
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p194
+sg15
+I01
+sg23
+(lp195
+S'BUGCR33099'
+p196
+asasg16
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p197
+ssS'media/track/track-webvtt-tc022-entities.html'
+p198
+(dp199
+g8
+g20
+sg16
+S'Tests special characters &amp;, &lt;, and &gt; in the cue text.'
+p200
+ssS'http/tests/media/video-buffered.html'
+p201
+(dp202
+g8
+(lp203
+(dp204
+g11
+I01
+sg23
+(lp205
+S'BUGCR49165'
+p206
+asg13
+S' video.buffered multiple TimeRanges support.'
+p207
+sg69
+I01
+sasg16
+g84
+ssS'media/track/track-webvtt-tc012-out-of-order.html'
+p208
+(dp209
+g8
+g20
+sg16
+S'Tests that cues that are temporally out of order are ignored.'
+p210
+ssS'media/track/track-webvtt-tc010-no-timings.html'
+p211
+(dp212
+g8
+g20
+sg16
+S'Tests cue without timings are ignored.'
+p213
+ssS'media/track/track-webvtt-tc001-utf8.html'
+p214
+(dp215
+g8
+g20
+sg16
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as a WebVTT file (we do allow it, it just looks ugly).'
+p216
+ssS'media/track/track-webvtt-tc006-cue-identifiers.html'
+p217
+(dp218
+g8
+g20
+sg16
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p219
+ssS'media/track/track-webvtt-tc013-settings.html'
+p220
+(dp221
+g8
+g20
+sg16
+S'Tests WebVTT settings.'
+p222
+ssS'media/track/track-webvtt-tc017-line-position.html'
+p223
+(dp224
+g8
+g20
+sg16
+S'Tests cue line position from settings.'
+p225
+ssS'media/track/track-webvtt-tc016-align-positioning.html'
+p226
+(dp227
+g8
+g20
+sg16
+S'Tests cue text position and alignment from settings.'
+p228
+ssS'media/track/track-webvtt-tc005-header-comment.html'
+p229
+(dp230
+g8
+g20
+sg16
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p231
+ssS'media/track/track-webvtt-tc015-positioning.html'
+p232
+(dp233
+g8
+g20
+sg16
+S'Tests cue text position from settings.'
+p234
+ssS'media/track/track-webvtt-tc009-timings-hour.html'
+p235
+(dp236
+g8
+g20
+sg16
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p237
+ssS'media/track/track-webvtt-tc027-empty-cue.html'
+p238
+(dp239
+g8
+g20
+sg16
+S'Tests that empty cues are discarded.'
+p240
+ssS'media/track/track-webvtt-tc028-unsupported-markup.html'
+p241
+(dp242
+g8
+g20
+sg16
+S'Tests that unsupported markup is properly ignored.'
+p243
+ssS'media/track/track-webvtt-tc023-markup.html'
+p244
+(dp245
+g8
+g20
+sg16
+S'Tests cues with &lt;b&gt;, &lt;i&gt;, &lt;u&gt;, &lt;rt&gt; and &lt;ruby&gt; tags.'
+p246
+ssS'media/video-element-other-namespace-crash.html'
+p247
+(dp248
+g8
+(lp249
+(dp250
+g11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+g84
+ssS'media/video-reverse-play-duration.html'
+p251
+(dp252
+g8
+(lp253
+(dp254
+g11
+I01
+sg13
+g194
+sg15
+I01
+sg23
+(lp255
+S'BUGCR33099'
+p256
+asasg16
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p257
+ssS'media/track/track-webvtt-tc025-class-markup.html'
+p258
+(dp259
+g8
+g20
+sg16
+S'Tests cues with class markup &lt;c&gt;.'
+p260
+sssS'whole'
+p261
+(dp262
+S'media/video-source-type.html'
+p263
+(dp264
+g16
+S'&lt;source&gt; @type attribute'
+p265
+ssS'media/media-startTime.html'
+p266
+(dp267
+g16
+S"Test the, so far unused, 'startTime' attribute."
+p268
+ssS'media/video-src-set.html'
+p269
+(dp270
+g16
+S'Test that setting src attribute triggers load'
+p271
+ssg27
+g28
+sS'media/video-played-ranges-1.html'
+p272
+(dp273
+g16
+S"Test of the media element 'played' attribute, ranges part 1."
+p274
+ssS'http/tests/media/video-play-stall-seek.html'
+p275
+(dp276
+g8
+(lp277
+(dp278
+g13
+S' Timing out.'
+p279
+sg15
+I01
+sg23
+(lp280
+S'BUGCR78376'
+p281
+asasg16
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p282
+ssg71
+g72
+sg85
+g86
+sg90
+g91
+sg124
+g125
+sS'media/controls-after-reload.html'
+p283
+(dp284
+g16
+S'Making sure the controller looks ok after a second load().'
+p285
+ssS'http/tests/media/video-referer.html'
+p286
+(dp287
+g16
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p288
+ssS'media/video-source-removed.html'
+p289
+(dp290
+g16
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p291
+ssS'media/unsupported-tracks.html'
+p292
+(dp293
+g16
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p294
+ssg111
+g112
+sS'media/audio-no-installed-engines.html'
+p295
+(dp296
+g16
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p297
+ssg116
+g117
+sS'media/video-width-height.html'
+p298
+(dp299
+g16
+g84
+ssS'media/media-blocked-by-willsendrequest.html'
+p300
+(dp301
+g16
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p302
+ssS'media/video-error-does-not-exist.html'
+p303
+(dp304
+g16
+S'Test that the media element is in correct state after load fails.'
+p305
+ssS'media/video-play-pause-events.html'
+p306
+(dp307
+g16
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p308
+ssS'media/video-display-none-crash.html'
+p309
+(dp310
+g16
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p311
+ssg244
+g245
+sS'media/video-src-plus-source.html'
+p312
+(dp313
+g16
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p314
+ssS'media/video-source-none-supported.html'
+p315
+(dp316
+g16
+S'no usable &lt;source&gt; test'
+p317
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p318
+(dp319
+g16
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p320
+ssg6
+g7
+sS'media/video-src.html'
+p321
+(dp322
+g16
+g84
+ssg168
+g169
+sS'media/video-src-invalid-poster.html'
+p323
+(dp324
+g16
+g84
+ssS'media/video-source-inserted.html'
+p325
+(dp326
+g16
+S'networkState after inserting &lt;source&gt; test'
+p327
+ssS'media/media-can-play-octet-stream.html'
+p328
+(dp329
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p330
+ssS'media/constructors.html'
+p331
+(dp332
+g16
+S'Test that media constructors behave consistently.'
+p333
+ssS'media/video-source-media.html'
+p334
+(dp335
+g16
+g84
+ssg201
+g202
+sS'media/video-aspect-ratio.html'
+p336
+(dp337
+g16
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p338
+ssg214
+g215
+sS'media/video-source-type-params.html'
+p339
+(dp340
+g16
+g84
+ssS'fast/canvas/webgl/context-lost.html'
+p341
+(dp342
+g16
+S'debug("Test valid context");'
+p343
+ssS'media/media-can-play-wav-audio.html'
+p344
+(dp345
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p346
+ssS'media/video-source-error.html'
+p347
+(dp348
+g8
+(lp349
+(dp350
+S'DEBUG'
+p351
+I01
+sg52
+I01
+sg23
+(lp352
+S'BUGWK66310'
+p353
+asg13
+S''
+p354
+sg69
+I01
+sasg16
+S'&lt;video&gt; and &lt;source&gt; error test'
+p355
+ssg223
+g224
+sg226
+g227
+sS'media/video-no-audio.html'
+p356
+(dp357
+g16
+S'Movie with no audio track. The volume button should not render.'
+p358
+ssS'media/svg-as-image-with-media-blocked.html'
+p359
+(dp360
+g16
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p361
+ssS'media/video-transformed.html'
+p362
+(dp363
+g8
+(lp364
+(dp365
+S'WIN'
+p366
+I01
+sg48
+I01
+sg23
+(lp367
+S'BUGWK66437'
+p368
+asg13
+g354
+sg83
+I01
+sg53
+I01
+sasg16
+S'Test painting of transformed video'
+p369
+ssS'media/video-click-dblckick-standalone.html'
+p370
+(dp371
+g16
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p372
+ssS'media/video-pause-immediately.html'
+p373
+(dp374
+g16
+S'Test that pausing the media element has an immediate effect on the clock.'
+p375
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p376
+(dp377
+g16
+g84
+ssg251
+g252
+sS'http/tests/security/local-video-src-from-remote.html'
+p378
+(dp379
+g16
+S'This test only works in DRT'
+p380
+ssg43
+g44
+sS'media/video-controls-in-media-document.html'
+p381
+(dp382
+g16
+g84
+ssS'media/remove-from-document-no-load.html'
+p383
+(dp384
+g16
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p385
+ssS'media/video-currentTime.html'
+p386
+(dp387
+g16
+g84
+ssS'media/video-frame-accurate-seek.html'
+p388
+(dp389
+g8
+(lp390
+(dp391
+g48
+I01
+sg23
+(lp392
+S'BUGCR72223'
+p393
+asg13
+g354
+sg69
+I01
+sasg16
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p394
+ssg18
+g19
+sg37
+g38
+sg180
+g181
+sS'media/media-controls-clone-crash.html'
+p395
+(dp396
+g16
+S'Test passes if it does not crash.'
+p397
+ssS'media/controls-css-overload.html'
+p398
+(dp399
+g16
+S"Testing that overloading some controls doesn't crash the browser"
+p400
+ssS'media/video-display-aspect-ratio.html'
+p401
+(dp402
+g16
+g84
+ssS'media/video-currentTime-set.html'
+p403
+(dp404
+g16
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p405
+ssS'media/media-blocked-by-beforeload.html'
+p406
+(dp407
+g8
+(lp408
+(dp409
+g52
+I01
+sg23
+(lp410
+S'BUGWK66310'
+p411
+asg13
+g354
+sg69
+I01
+sasg16
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p412
+ssS'media/video-controls-visible-audio-only.html'
+p413
+(dp414
+g16
+S'This test only runs in DRT!'
+p415
+ssS'http/tests/media/video-play-progress.html'
+p416
+(dp417
+g16
+S'Test that at least one progress event is fired after starting to load the video.'
+p418
+ssg106
+g107
+sS'media/controls-styling.html'
+p419
+(dp420
+g16
+S'The look of the controls should not change.'
+p421
+ssS'media/video-source-moved.html'
+p422
+(dp423
+g16
+S'moving &lt;source&gt; element test'
+p424
+ssS'http/tests/security/local-video-source-from-remote.html'
+p425
+(dp426
+g16
+S'This test only behaves correctly in DRT'
+p427
+ssS'media/video-src-none.html'
+p428
+(dp429
+g16
+g84
+ssS'media/video-controls-zoomed.html'
+p430
+(dp431
+g16
+S'This test only runs in DRT!'
+p432
+ssS'media/video-load-networkState.html'
+p433
+(dp434
+g16
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p435
+ssS'media/video-controls.html'
+p436
+(dp437
+g16
+S"Test 'controls' attribute"
+p438
+ssS'media/controls-without-preload.html'
+p439
+(dp440
+g16
+S'The controls should not depend on preload value.'
+p441
+ssS'media/video-played-collapse.html'
+p442
+(dp443
+g16
+S"Test of the media element 'played' attribute"
+p444
+ssS'compositing/self-painting-layers.html'
+p445
+(dp446
+g16
+S'Self painting layers'
+p447
+ssS'media/audio-controls-do-not-fade-out.html'
+p448
+(dp449
+g16
+S'This tests that audio controls do not fade out when the audio is playing.'
+p450
+ssg149
+g150
+sg152
+g153
+sS'compositing/geometry/video-opacity-overlay.html'
+p451
+(dp452
+g16
+S'Video overlay'
+p453
+ssS'media/video-source-error-no-candidate.html'
+p454
+(dp455
+g16
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p456
+ssS'media/audio-constructor.html'
+p457
+(dp458
+g16
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p459
+ssg174
+g175
+sS'media/event-attributes.html'
+p460
+(dp461
+g16
+g84
+ssg190
+g191
+sg208
+g209
+sS'http/tests/media/text-served-as-text.html'
+p462
+(dp463
+g16
+S"text file served as 'text/plain'"
+p464
+ssg211
+g212
+sS'http/tests/media/video-cancel-load.html'
+p465
+(dp466
+g16
+S'Cancel loading a video file and access its properties afterwards.'
+p467
+ssS'media/unsupported-rtsp.html'
+p468
+(dp469
+g16
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p470
+ssS'media/media-controls-clone.html'
+p471
+(dp472
+g16
+S'<video controls id=v></video><audio controls id=a></audio>'
+p473
+ssS'media/broken-video.html'
+p474
+(dp475
+g16
+S'Test that QuickTime file with broken content generates an error.'
+p476
+ssS'media/video-plays-past-end-of-test.html'
+p477
+(dp478
+g16
+g84
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p479
+(dp480
+g16
+S'WebGL Origin Restrictions Conformance Tests'
+p481
+ssS'media/video-replaces-poster.html'
+p482
+(dp483
+g16
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p484
+ssS'media/video-autoplay.html'
+p485
+(dp486
+g16
+g84
+ssS'media/video-set-rate-from-pause.html'
+p487
+(dp488
+g16
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p489
+ssg198
+g199
+sg229
+g230
+sS'media/video-src-remove.html'
+p490
+(dp491
+g16
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p492
+ssS'media/csp-blocks-video.html'
+p493
+(dp494
+g16
+S"This test passes if it doesn't alert failure."
+p495
+ssS'media/controls-drag-timebar.html'
+p496
+(dp497
+g16
+S'Test that dragging the timebar thumb causes seeks.'
+p498
+ssg232
+g233
+sS'media/audio-constructor-preload.html'
+p499
+(dp500
+g16
+S"Test that Audio() sets 'preload' attribute."
+p501
+ssS'media/video-poster-delayed.html'
+p502
+(dp503
+g16
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p504
+ssS'media/adopt-node-crash.html'
+p505
+(dp506
+g16
+S"Tests that we don't crash when moving a video element to a new document."
+p507
+ssS'media/media-initialTime.html'
+p508
+(dp509
+g16
+S"Test the, so far unused, 'initialTime' attribute."
+p510
+ssS'media/video-playbackrate.html'
+p511
+(dp512
+g16
+S'test playbackRate and defaultPlaybackRate'
+p513
+ssS'media/video-muted.html'
+p514
+(dp515
+g16
+S"Test 'muted' attribute"
+p516
+ssg241
+g242
+sS'media/video-src-change.html'
+p517
+(dp518
+g16
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p519
+ssS'compositing/overflow/overflow-compositing-descendant.html'
+p520
+(dp521
+g16
+S'You should see a green box under the video. If you see red, the test failed.'
+p522
+ssg247
+g248
+sS'media/video-play-pause-exception.html'
+p523
+(dp524
+g16
+S'Video has no src. Test that the playing event is not dispatched.'
+p525
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p526
+(dp527
+g16
+g84
+ssS'media/audio-play-event.html'
+p528
+(dp529
+g16
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p530
+ssS'media/before-load-member-access.html'
+p531
+(dp532
+g16
+S'Test that accessing member of a non loaded video works.'
+p533
+ssS'media/video-dom-src.html'
+p534
+(dp535
+g16
+g84
+ssg135
+g136
+sS'media/audio-repaint.html'
+p536
+(dp537
+g8
+(lp538
+(dp539
+g366
+I01
+sg48
+I01
+sg23
+(lp540
+S'BUGWK65203'
+p541
+asg13
+S' These should be rebaselined after the patch lands, as we are now drawing all text with skia (instead of gdi) and in these cases, we have differences in antialiasing (drt specific) or in fractional-baselines (gdi rounds in src space, skia rounds in devices space '
+p542
+sasg16
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p543
+ssS'media/audio-controls-rendering.html'
+p544
+(dp545
+g16
+S'Test controls placement.'
+p546
+ssg220
+g221
+sS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p547
+(dp548
+g16
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p549
+ssS'media/invalid-media-url-crash.html'
+p550
+(dp551
+g16
+S'Tests that invalid media src url does not result in crash.'
+p552
+ssS'media/video-empty-source.html'
+p553
+(dp554
+g16
+S'Slider drawing with no source. The controls should render correctly.'
+p555
+ssg98
+g99
+sS'media/video-poster.html'
+p556
+(dp557
+g16
+S'Test &lt;video&gt; element with and without a poster.'
+p558
+ssS'media/media-document-audio-size.html'
+p559
+(dp560
+g16
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p561
+ssS'media/video-zoom.html'
+p562
+(dp563
+g16
+S'150% zoom, with width and height attributes'
+p564
+ssS'http/tests/appcache/video.html'
+p565
+(dp566
+g16
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p567
+ssg127
+g128
+sS'media/video-dom-autoplay.html'
+p568
+(dp569
+g16
+g84
+ssS'media/media-ended.html'
+p570
+(dp571
+g16
+S'<b>Test ended by:</b>'
+p572
+ssS'media/video-no-autoplay.html'
+p573
+(dp574
+g16
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p575
+ssg130
+g131
+sS'media/video-append-source.html'
+p576
+(dp577
+g16
+g84
+ssg138
+g139
+sS'http/tests/media/pdf-served-as-pdf.html'
+p578
+(dp579
+g16
+S"PDF file served as 'application/pdf'"
+p580
+ssS'media/video-play-empty-events.html'
+p581
+(dp582
+g16
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p583
+ssg146
+g147
+sS'media/audio-only-video-intrinsic-size.html'
+p584
+(dp585
+g16
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p586
+ssg141
+g142
+sS'http/tests/media/video-error-abort.html'
+p587
+(dp588
+g16
+S"'abort' event test"
+p589
+ssS'media/audio-delete-while-slider-thumb-clicked.html'
+p590
+(dp591
+g16
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p592
+ssS'media/media-can-play-ogg.html'
+p593
+(dp594
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p595
+ssg159
+g160
+sS'media/video-currentTime-set2.html'
+p596
+(dp597
+g16
+g84
+ssS'media/video-seekable.html'
+p598
+(dp599
+g16
+g84
+ssS'fast/dom/beforeload/video-before-load.html'
+p600
+(dp601
+g16
+g84
+ssS'media/video-played-reset.html'
+p602
+(dp603
+g16
+S"Test of the media element 'played' attribute"
+p604
+ssg177
+g178
+sS'compositing/self-painting-layers2.html'
+p605
+(dp606
+g16
+S'This test should not assert in debug builds.'
+p607
+ssg165
+g166
+sS'media/controls-right-click-on-timebar.html'
+p608
+(dp609
+g16
+S'Test that right clicking on the timebar does not cause a seek.'
+p610
+ssS'media/video-dom-preload.html'
+p611
+(dp612
+g16
+S'consoleWrite("++ Test default attribute value");'
+p613
+ssS'media/video-size.html'
+p614
+(dp615
+g16
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p616
+ssS'media/video-load-preload-none.html'
+p617
+(dp618
+g16
+S'Test that an explicit load() to a media element whose preload is set to "none" still loads the video.'
+p619
+ssS'media/video-delay-load-event.html'
+p620
+(dp621
+g8
+(lp622
+(dp623
+g52
+I01
+sg23
+(lp624
+S'BUGWK64003'
+p625
+asg13
+S' Started around WebKit r90233:r90242'
+p626
+sg83
+I01
+sg69
+I01
+sg351
+I01
+sasg16
+S"Test the document's load event is delayed until a movie's meta data is available."
+p627
+ssS'media/fallback.html'
+p628
+(dp629
+g16
+S'Test that fallback content is not rendered'
+p630
+ssS'media/video-layer-crash.html'
+p631
+(dp632
+g8
+(lp633
+(dp634
+g366
+I01
+sg48
+I01
+sg23
+(lp635
+S'BUGWK66437'
+p636
+asg13
+g354
+sg83
+I01
+sg53
+I01
+sasg16
+S'Test dynamic removal of transformed and reflected video'
+p637
+ssS'fast/layers/video-layer.html'
+p638
+(dp639
+g16
+S'Video element gets layer'
+p640
+ssS'media/controls-strict.html'
+p641
+(dp642
+g16
+S'Drawing the controls in strict mode.'
+p643
+ssS'media/remove-from-document.html'
+p644
+(dp645
+g16
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p646
+ssS'http/tests/media/remove-while-loading.html'
+p647
+(dp648
+g16
+S'Test that removing a media element from the tree while loading does not crash.'
+p649
+ssS'media/video-controls-transformed.html'
+p650
+(dp651
+g16
+S'This test only runs in DRT!'
+p652
+ssS'compositing/video/video-poster.html'
+p653
+(dp654
+g16
+S'Video with poster'
+p655
+ssS'media/video-display-toggle.html'
+p656
+(dp657
+g16
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p658
+ssS'media/video-seek-no-src-exception.html'
+p659
+(dp660
+g16
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p661
+ssS'media/audio-constructor-src.html'
+p662
+(dp663
+g16
+S'Test that Audio("url") constructor loads the specified resource.'
+p664
+ssS'compositing/geometry/clipped-video-controller.html'
+p665
+(dp666
+g16
+S'Clipped Video'
+p667
+ssg238
+g239
+sS'media/video-preload.html'
+p668
+(dp669
+g16
+S"Test to see if media loads automatically when 'preload' is specified."
+p670
+ssS'http/tests/media/video-load-twice.html'
+p671
+(dp672
+g16
+g84
+ssS'http/tests/media/video-cookie.html'
+p673
+(dp674
+g16
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p675
+ssS'media/video-source.html'
+p676
+(dp677
+g16
+g84
+ssS'media/video-seek-past-end-playing.html'
+p678
+(dp679
+g16
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p680
+ssS'media/video-currentTime-delay.html'
+p681
+(dp682
+g16
+S'Test a delay in playing the movie results in a canPlay event.'
+p683
+ssS'http/tests/media/reload-after-dialog.html'
+p684
+(dp685
+g16
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p686
+ssg217
+g218
+sS'media/media-constants.html'
+p687
+(dp688
+g16
+S'Test HTMLMediaElement and MediaError constants.'
+p689
+ssS'media/media-controls-invalid-url.html'
+p690
+(dp691
+g16
+S'This tests that media element controls are reset to their default state when the src is changed to an invalid url.'
+p692
+ssS'media/video-volume.html'
+p693
+(dp694
+g16
+S"Test 'volume' attribute"
+p695
+ssS'media/video-src-source.html'
+p696
+(dp697
+g16
+g84
+ssS'media/video-buffered.html'
+p698
+(dp699
+g16
+g84
+ssg64
+g65
+sS'media/video-source-load.html'
+p700
+(dp701
+g16
+S'Test that the resource selection algorithm is restarted when load() is called, and that all &lt;source&gt; elements are reconsidered.'
+p702
+ssg76
+g77
+sS'media/video-canvas-source.html'
+p703
+(dp704
+g16
+S'Drawing to canvas using video with source element does not taint canvas'
+p705
+ssS'media/video-controls-no-scripting.html'
+p706
+(dp707
+g16
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p708
+ssS'media/video-poster-scale.html'
+p709
+(dp710
+g16
+S"'poster' aspect ratio test"
+p711
+ssS'media/video-seek-by-small-increment.html'
+p712
+(dp713
+g16
+S'Test seeking by very small increments.'
+p714
+ssg103
+g104
+sS'media/video-controls-with-mutation-event-handler.html'
+p715
+(dp716
+g16
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p717
+ssS'media/video-zoom-controls.html'
+p718
+(dp719
+g16
+S'Zoomed video with controls.'
+p720
+ssS'media/video-loop.html'
+p721
+(dp722
+g8
+(lp723
+(dp724
+g366
+I01
+sg69
+I01
+sg23
+(lp725
+S'BUGCR59415'
+p726
+asg13
+S' BUGCR59415 : cannot repro the flakiness'
+p727
+sg15
+I01
+sg52
+I01
+sasg16
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p728
+ssS'http/tests/media/video-play-stall.html'
+p729
+(dp730
+g8
+(lp731
+(dp732
+g52
+I01
+sg23
+(lp733
+S'BUGCR73609'
+p734
+asg13
+S' canplaythrough event is sent too early.'
+p735
+sasg16
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p736
+ssS'media/video-seeking.html'
+p737
+(dp738
+g16
+S'Test that seeking attribute is true immediately after a seek,'
+p739
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p740
+(dp741
+g16
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p742
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p743
+(dp744
+g16
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p745
+ssg55
+g56
+sg162
+g163
+sS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p746
+(dp747
+g16
+g84
+ssS'compositing/reflections/load-video-in-reflection.html'
+p748
+(dp749
+g16
+S'You should see a reflected video below, rather than the red video background.'
+p750
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p751
+(dp752
+g16
+S'Video overlay'
+p753
+ssS'media/video-controls-rendering.html'
+p754
+(dp755
+g8
+(lp756
+(dp757
+g53
+I01
+sg48
+I01
+sg23
+(lp758
+S'BUGCR94409'
+p759
+asg13
+S' Flaky scrollbar issues'
+p760
+sS'LINUX'
+p761
+I01
+sasg16
+S'Test controls placement.'
+p762
+ssS'http/tests/media/video-served-as-text.html'
+p763
+(dp764
+g16
+S"media file served as 'text/plain'"
+p765
+ssS'media/video-pause-empty-events.html'
+p766
+(dp767
+g16
+S'Test that pause() from EMPTY network state triggers load()'
+p768
+ssg61
+g62
+sS'media/media-load-event.html'
+p769
+(dp770
+g16
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p771
+ssS'media/video-defaultmuted.html'
+p772
+(dp773
+g16
+S'consoleWrite("<br><br><b>*** Test <em>" + (defaultMuted ? "with" : "without") + "</em> \'muted\' content attribute</b><br>");'
+p774
+ssS'media/video-volume-slider.html'
+p775
+(dp776
+g16
+S'Test rendering of volume slider of video tag'
+p777
+ssS'media/video-seek-past-end-paused.html'
+p778
+(dp779
+g16
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p780
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p781
+(dp782
+g16
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p783
+ssS'media/remove-from-document-before-load.html'
+p784
+(dp785
+g16
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p786
+ssS'media/video-duration-known-after-eos.html'
+p787
+(dp788
+g16
+S'Tests that duration is known after playback ended.'
+p789
+ssS'http/tests/media/video-play-stall-before-meta-data.html'
+p790
+(dp791
+g16
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p792
+ssS'media/video-timeupdate-during-playback.html'
+p793
+(dp794
+g16
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p795
+ssS'media/video-single-valid-source.html'
+p796
+(dp797
+g16
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p798
+ssS'media/video-src-invalid-remove.html'
+p799
+(dp800
+g16
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p801
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p802
+(dp803
+g16
+S"This test passes if it doesn't alert failure."
+p804
+ssg235
+g236
+sg258
+g259
+sS'media/video-load-readyState.html'
+p805
+(dp806
+g16
+g84
+sssS'nonskip'
+p807
+(dp808
+g388
+g389
+sg721
+g722
+sg536
+g537
+sg729
+g730
+sg275
+g276
+sg362
+g363
+sg754
+g755
+sg620
+g621
+sg631
+g632
+sg406
+g407
+sg347
+g348
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/result/2011-09-11-19 b/chromium/media/tools/layout_tests/result/2011-09-11-19
new file mode 100644
index 00000000000..8cb30479b8d
--- /dev/null
+++ b/chromium/media/tools/layout_tests/result/2011-09-11-19
@@ -0,0 +1,2047 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/video-does-not-loop.html'
+p6
+(dp7
+S'te_info'
+p8
+(lp9
+(dp10
+S'SKIP'
+p11
+I01
+sS'WONTFIX'
+p12
+I01
+sS'Comments'
+p13
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p14
+sS'TIMEOUT'
+p15
+I01
+sasS'desc'
+p16
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p17
+ssS'media/track/track-webvtt-tc020-cue-size-align.html'
+p18
+(dp19
+g8
+(lp20
+(dp21
+g11
+I01
+sg13
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p22
+sg15
+I01
+sS'Bugs'
+p23
+(lp24
+S'BUGWK43668'
+p25
+asasg16
+S'Tests cue size and alignment from settings.'
+p26
+ssS'media/audio-delete-while-step-button-clicked.html'
+p27
+(dp28
+g8
+(lp29
+(dp30
+S'FAIL'
+p31
+I01
+sg11
+I01
+sg23
+(lp32
+S'BUGCR25375'
+p33
+aS'BUGCR59399'
+p34
+asg13
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p35
+sasg16
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p36
+ssS'media/restore-from-page-cache.html'
+p37
+(dp38
+g8
+(lp39
+(dp40
+g11
+I01
+sg12
+I01
+sg13
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p41
+sg15
+I01
+sasg16
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p42
+ssS'media/media-document-audio-repaint.html'
+p43
+(dp44
+g8
+(lp45
+(dp46
+S'IMAGE+TEXT'
+p47
+I01
+sg11
+I01
+sS'IMAGE'
+p48
+I01
+sg23
+(lp49
+S'BUGCR94918'
+p50
+asg13
+S' Skip test test since this test uses layoutTestController.display() that needs to be implemented for GPU'
+p51
+sS'TEXT'
+p52
+I01
+sS'GPU'
+p53
+I01
+sasg16
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p54
+ssS'media/media-can-play-mpeg4-video.html'
+p55
+(dp56
+g8
+(lp57
+(dp58
+g11
+I01
+sg12
+I01
+sg13
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p59
+sg52
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p60
+ssS'media/track/track-webvtt-tc007-cue-no-id.html'
+p61
+(dp62
+g8
+g20
+sg16
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p63
+ssS'http/tests/media/video-cross-site.html'
+p64
+(dp65
+g8
+(lp66
+(dp67
+g11
+I01
+sg13
+S' QuickTime reference movies not supported.'
+p68
+sg15
+I01
+sS'PASS'
+p69
+I01
+sg31
+I01
+sg12
+I01
+sasg16
+S'media file redirects to another site'
+p70
+ssS'media/audio-data-url.html'
+p71
+(dp72
+g8
+(lp73
+(dp74
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that audio element can use a data: url'
+p75
+ssS'media/video-canvas-alpha.html'
+p76
+(dp77
+g8
+(lp78
+(dp79
+g11
+I01
+sg48
+I01
+sg23
+(lp80
+S'BUGCR74979'
+p81
+asg13
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p82
+sS'MAC'
+p83
+I01
+sg53
+I01
+sasg16
+S'UNKNOWN'
+p84
+ssS'media/video-can-play-type.html'
+p85
+(dp86
+g8
+(lp87
+(dp88
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p89
+ssS'media/media-captions.html'
+p90
+(dp91
+g8
+(lp92
+(dp93
+g11
+I01
+sg13
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p94
+sg15
+I01
+sg23
+(lp95
+S'BUGCR28301'
+p96
+asasg16
+S'Test media element close caption API.'
+p97
+ssS'media/video-size-intrinsic-scale.html'
+p98
+(dp99
+g8
+(lp100
+(dp101
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'&lt;video&gt; element intrinsic size test'
+p102
+ssS'media/track/track-webvtt-tc004-magic-header.html'
+p103
+(dp104
+g8
+g20
+sg16
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p105
+ssS'media/media-can-play-mpeg-audio.html'
+p106
+(dp107
+g8
+(lp108
+(dp109
+g11
+I01
+sg12
+I01
+sg13
+g59
+sg52
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p110
+ssS'media/audio-mpeg4-supported.html'
+p111
+(dp112
+g8
+(lp113
+(dp114
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that the audio element supports M4A files.'
+p115
+ssS'media/media-fullscreen-not-in-document.html'
+p116
+(dp117
+g8
+(lp118
+(dp119
+g11
+I01
+sg13
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p120
+sg15
+I01
+sg23
+(lp121
+S'BUGCR16735'
+p122
+asasg16
+S'Test media element fullscreen API when an element is not in the DOM.'
+p123
+ssS'media/track/track-webvtt-tc014-alignment.html'
+p124
+(dp125
+g8
+g20
+sg16
+S'Tests cue alignment from settings.'
+p126
+ssS'media/track/track-webvtt-tc021-valign.html'
+p127
+(dp128
+g8
+g20
+sg16
+S'Tests cue vertical alignment (direction) from settings.'
+p129
+ssS'media/audio-mpeg-supported.html'
+p130
+(dp131
+g8
+(lp132
+(dp133
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S'Test that the audio element supports MPEG files.'
+p134
+ssS'media/track/track-webvtt-tc019-cue-size.html'
+p135
+(dp136
+g8
+g20
+sg16
+S'Tests cue size from settings.'
+p137
+ssS'media/track/track-webvtt-tc003-newlines.html'
+p138
+(dp139
+g8
+g20
+sg16
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p140
+ssS'media/video-document-types.html'
+p141
+(dp142
+g8
+(lp143
+(dp144
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p145
+ssS'media/track/track-webvtt-tc024-timestamp.html'
+p146
+(dp147
+g8
+g20
+sg16
+S'Tests cues with &lt;timestamps&gt; tags.'
+p148
+ssS'media/track/track-webvtt-tc008-timings-no-hours.html'
+p149
+(dp150
+g8
+g20
+sg16
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p151
+ssS'media/media-fullscreen-inline.html'
+p152
+(dp153
+g8
+(lp154
+(dp155
+g11
+I01
+sg13
+g120
+sg15
+I01
+sg23
+(lp156
+S'BUGCR16735'
+p157
+asasg16
+S'Test media element fullscreen API when an element is in the DOM.'
+p158
+ssS'media/track/track-webvtt-tc000-empty.html'
+p159
+(dp160
+g8
+g20
+sg16
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p161
+ssS'media/track/track-webvtt-tc018-align-text-line-position.html'
+p162
+(dp163
+g8
+g20
+sg16
+S'Tests cue alignment, line and text position from settings.'
+p164
+ssS'media/track/track-webvtt-tc002-bom.html'
+p165
+(dp166
+g8
+g20
+sg16
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p167
+ssS'compositing/video/video-background-color.html'
+p168
+(dp169
+g8
+(lp170
+(dp171
+g31
+I01
+sg11
+I01
+sg12
+I01
+sg13
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p172
+sasg16
+S'Video with background color'
+p173
+ssS'media/track/track-webvtt-tc026-voice.html'
+p174
+(dp175
+g8
+g20
+sg16
+S'Tests cues with voice markup &lt;v&gt;.'
+p176
+ssS'media/track/track-webvtt-tc011-blank-lines.html'
+p177
+(dp178
+g8
+g20
+sg16
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p179
+ssS'media/context-menu-actions.html'
+p180
+(dp181
+g8
+(lp182
+(dp183
+S'CRASH'
+p184
+I01
+sg11
+I01
+sg23
+(lp185
+S'BUGCR59665'
+p186
+aS'BUGWK45021'
+p187
+asg13
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p188
+sg15
+I01
+sg69
+I01
+sasg16
+S'Test the various actions available in the HTML5 media element context-menu.'
+p189
+ssS'media/video-timeupdate-reverse-play.html'
+p190
+(dp191
+g8
+(lp192
+(dp193
+g11
+I01
+sg13
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p194
+sg15
+I01
+sg23
+(lp195
+S'BUGCR33099'
+p196
+asasg16
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p197
+ssS'media/track/track-webvtt-tc022-entities.html'
+p198
+(dp199
+g8
+g20
+sg16
+S'Tests special characters &amp;, &lt;, and &gt; in the cue text.'
+p200
+ssS'http/tests/media/video-buffered.html'
+p201
+(dp202
+g8
+(lp203
+(dp204
+g11
+I01
+sg23
+(lp205
+S'BUGCR49165'
+p206
+asg13
+S' video.buffered multiple TimeRanges support.'
+p207
+sg69
+I01
+sasg16
+g84
+ssS'media/track/track-webvtt-tc012-out-of-order.html'
+p208
+(dp209
+g8
+g20
+sg16
+S'Tests that cues that are temporally out of order are ignored.'
+p210
+ssS'media/track/track-webvtt-tc010-no-timings.html'
+p211
+(dp212
+g8
+g20
+sg16
+S'Tests cue without timings are ignored.'
+p213
+ssS'media/track/track-webvtt-tc001-utf8.html'
+p214
+(dp215
+g8
+g20
+sg16
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as a WebVTT file (we do allow it, it just looks ugly).'
+p216
+ssS'media/track/track-webvtt-tc006-cue-identifiers.html'
+p217
+(dp218
+g8
+g20
+sg16
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p219
+ssS'media/track/track-webvtt-tc013-settings.html'
+p220
+(dp221
+g8
+g20
+sg16
+S'Tests WebVTT settings.'
+p222
+ssS'media/track/track-webvtt-tc017-line-position.html'
+p223
+(dp224
+g8
+g20
+sg16
+S'Tests cue line position from settings.'
+p225
+ssS'media/track/track-webvtt-tc016-align-positioning.html'
+p226
+(dp227
+g8
+g20
+sg16
+S'Tests cue text position and alignment from settings.'
+p228
+ssS'media/track/track-webvtt-tc005-header-comment.html'
+p229
+(dp230
+g8
+g20
+sg16
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p231
+ssS'media/track/track-webvtt-tc015-positioning.html'
+p232
+(dp233
+g8
+g20
+sg16
+S'Tests cue text position from settings.'
+p234
+ssS'media/track/track-webvtt-tc009-timings-hour.html'
+p235
+(dp236
+g8
+g20
+sg16
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p237
+ssS'media/track/track-webvtt-tc027-empty-cue.html'
+p238
+(dp239
+g8
+g20
+sg16
+S'Tests that empty cues are discarded.'
+p240
+ssS'media/track/track-webvtt-tc028-unsupported-markup.html'
+p241
+(dp242
+g8
+g20
+sg16
+S'Tests that unsupported markup is properly ignored.'
+p243
+ssS'media/track/track-webvtt-tc023-markup.html'
+p244
+(dp245
+g8
+g20
+sg16
+S'Tests cues with &lt;b&gt;, &lt;i&gt;, &lt;u&gt;, &lt;rt&gt; and &lt;ruby&gt; tags.'
+p246
+ssS'media/video-element-other-namespace-crash.html'
+p247
+(dp248
+g8
+(lp249
+(dp250
+g11
+I01
+sg12
+I01
+sg13
+g59
+sg15
+I01
+sasg16
+g84
+ssS'media/video-reverse-play-duration.html'
+p251
+(dp252
+g8
+(lp253
+(dp254
+g11
+I01
+sg13
+g194
+sg15
+I01
+sg23
+(lp255
+S'BUGCR33099'
+p256
+asasg16
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p257
+ssS'media/track/track-webvtt-tc025-class-markup.html'
+p258
+(dp259
+g8
+g20
+sg16
+S'Tests cues with class markup &lt;c&gt;.'
+p260
+sssS'whole'
+p261
+(dp262
+S'media/video-source-type.html'
+p263
+(dp264
+g16
+S'&lt;source&gt; @type attribute'
+p265
+ssS'media/media-startTime.html'
+p266
+(dp267
+g16
+S"Test the, so far unused, 'startTime' attribute."
+p268
+ssS'media/video-src-set.html'
+p269
+(dp270
+g16
+S'Test that setting src attribute triggers load'
+p271
+ssg27
+g28
+sS'media/video-played-ranges-1.html'
+p272
+(dp273
+g16
+S"Test of the media element 'played' attribute, ranges part 1."
+p274
+ssS'http/tests/media/video-play-stall-seek.html'
+p275
+(dp276
+g8
+(lp277
+(dp278
+g13
+S' Timing out.'
+p279
+sg15
+I01
+sg23
+(lp280
+S'BUGCR78376'
+p281
+asasg16
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p282
+ssg71
+g72
+sg85
+g86
+sg90
+g91
+sg124
+g125
+sS'media/controls-after-reload.html'
+p283
+(dp284
+g16
+S'Making sure the controller looks ok after a second load().'
+p285
+ssS'http/tests/media/video-referer.html'
+p286
+(dp287
+g16
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p288
+ssS'media/video-source-removed.html'
+p289
+(dp290
+g16
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p291
+ssS'media/unsupported-tracks.html'
+p292
+(dp293
+g16
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p294
+ssg111
+g112
+sS'media/audio-no-installed-engines.html'
+p295
+(dp296
+g16
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p297
+ssg116
+g117
+sS'media/video-width-height.html'
+p298
+(dp299
+g16
+g84
+ssS'media/media-blocked-by-willsendrequest.html'
+p300
+(dp301
+g16
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p302
+ssS'media/video-error-does-not-exist.html'
+p303
+(dp304
+g16
+S'Test that the media element is in correct state after load fails.'
+p305
+ssS'media/video-play-pause-events.html'
+p306
+(dp307
+g16
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p308
+ssS'media/video-display-none-crash.html'
+p309
+(dp310
+g16
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p311
+ssg244
+g245
+sS'media/video-src-plus-source.html'
+p312
+(dp313
+g16
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p314
+ssS'media/video-source-none-supported.html'
+p315
+(dp316
+g16
+S'no usable &lt;source&gt; test'
+p317
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p318
+(dp319
+g16
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p320
+ssg6
+g7
+sS'media/video-src.html'
+p321
+(dp322
+g16
+g84
+ssg168
+g169
+sS'media/video-src-invalid-poster.html'
+p323
+(dp324
+g16
+g84
+ssS'media/video-source-inserted.html'
+p325
+(dp326
+g16
+S'networkState after inserting &lt;source&gt; test'
+p327
+ssS'media/media-can-play-octet-stream.html'
+p328
+(dp329
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p330
+ssS'media/constructors.html'
+p331
+(dp332
+g16
+S'Test that media constructors behave consistently.'
+p333
+ssS'media/video-source-media.html'
+p334
+(dp335
+g16
+g84
+ssg201
+g202
+sS'media/video-aspect-ratio.html'
+p336
+(dp337
+g16
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p338
+ssg214
+g215
+sS'media/video-source-type-params.html'
+p339
+(dp340
+g16
+g84
+ssS'fast/canvas/webgl/context-lost.html'
+p341
+(dp342
+g16
+S'debug("Test valid context");'
+p343
+ssS'media/media-can-play-wav-audio.html'
+p344
+(dp345
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p346
+ssS'media/video-source-error.html'
+p347
+(dp348
+g8
+(lp349
+(dp350
+S'DEBUG'
+p351
+I01
+sg52
+I01
+sg23
+(lp352
+S'BUGWK66310'
+p353
+asg13
+S''
+p354
+sg69
+I01
+sasg16
+S'&lt;video&gt; and &lt;source&gt; error test'
+p355
+ssg223
+g224
+sg226
+g227
+sS'media/video-no-audio.html'
+p356
+(dp357
+g16
+S'Movie with no audio track. The volume button should not render.'
+p358
+ssS'media/svg-as-image-with-media-blocked.html'
+p359
+(dp360
+g16
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p361
+ssS'media/video-transformed.html'
+p362
+(dp363
+g8
+(lp364
+(dp365
+S'WIN'
+p366
+I01
+sg48
+I01
+sg23
+(lp367
+S'BUGWK66437'
+p368
+asg13
+g354
+sg83
+I01
+sg53
+I01
+sasg16
+S'Test painting of transformed video'
+p369
+ssS'media/video-click-dblckick-standalone.html'
+p370
+(dp371
+g16
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p372
+ssS'media/video-pause-immediately.html'
+p373
+(dp374
+g16
+S'Test that pausing the media element has an immediate effect on the clock.'
+p375
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p376
+(dp377
+g16
+g84
+ssg251
+g252
+sS'http/tests/security/local-video-src-from-remote.html'
+p378
+(dp379
+g16
+S'This test only works in DRT'
+p380
+ssg43
+g44
+sS'media/video-controls-in-media-document.html'
+p381
+(dp382
+g16
+g84
+ssS'media/remove-from-document-no-load.html'
+p383
+(dp384
+g16
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p385
+ssS'media/video-currentTime.html'
+p386
+(dp387
+g16
+g84
+ssS'media/video-frame-accurate-seek.html'
+p388
+(dp389
+g8
+(lp390
+(dp391
+g48
+I01
+sg23
+(lp392
+S'BUGCR72223'
+p393
+asg13
+g354
+sg69
+I01
+sasg16
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p394
+ssg18
+g19
+sg37
+g38
+sg180
+g181
+sS'media/media-controls-clone-crash.html'
+p395
+(dp396
+g16
+S'Test passes if it does not crash.'
+p397
+ssS'media/controls-css-overload.html'
+p398
+(dp399
+g16
+S"Testing that overloading some controls doesn't crash the browser"
+p400
+ssS'media/video-display-aspect-ratio.html'
+p401
+(dp402
+g16
+g84
+ssS'media/video-currentTime-set.html'
+p403
+(dp404
+g16
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p405
+ssS'media/media-blocked-by-beforeload.html'
+p406
+(dp407
+g8
+(lp408
+(dp409
+g52
+I01
+sg23
+(lp410
+S'BUGWK66310'
+p411
+asg13
+g354
+sg69
+I01
+sasg16
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p412
+ssS'media/video-controls-visible-audio-only.html'
+p413
+(dp414
+g16
+S'This test only runs in DRT!'
+p415
+ssS'http/tests/media/video-play-progress.html'
+p416
+(dp417
+g16
+S'Test that at least one progress event is fired after starting to load the video.'
+p418
+ssg106
+g107
+sS'media/controls-styling.html'
+p419
+(dp420
+g16
+S'The look of the controls should not change.'
+p421
+ssS'media/video-source-moved.html'
+p422
+(dp423
+g16
+S'moving &lt;source&gt; element test'
+p424
+ssS'http/tests/security/local-video-source-from-remote.html'
+p425
+(dp426
+g16
+S'This test only behaves correctly in DRT'
+p427
+ssS'media/video-src-none.html'
+p428
+(dp429
+g16
+g84
+ssS'media/video-controls-zoomed.html'
+p430
+(dp431
+g16
+S'This test only runs in DRT!'
+p432
+ssS'media/video-load-networkState.html'
+p433
+(dp434
+g16
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p435
+ssS'media/video-controls.html'
+p436
+(dp437
+g16
+S"Test 'controls' attribute"
+p438
+ssS'media/controls-without-preload.html'
+p439
+(dp440
+g16
+S'The controls should not depend on preload value.'
+p441
+ssS'media/video-played-collapse.html'
+p442
+(dp443
+g16
+S"Test of the media element 'played' attribute"
+p444
+ssS'compositing/self-painting-layers.html'
+p445
+(dp446
+g16
+S'Self painting layers'
+p447
+ssS'media/audio-controls-do-not-fade-out.html'
+p448
+(dp449
+g16
+S'This tests that audio controls do not fade out when the audio is playing.'
+p450
+ssg149
+g150
+sg152
+g153
+sS'compositing/geometry/video-opacity-overlay.html'
+p451
+(dp452
+g16
+S'Video overlay'
+p453
+ssS'media/video-source-error-no-candidate.html'
+p454
+(dp455
+g16
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p456
+ssS'media/audio-constructor.html'
+p457
+(dp458
+g16
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p459
+ssg174
+g175
+sS'media/event-attributes.html'
+p460
+(dp461
+g16
+g84
+ssg190
+g191
+sg208
+g209
+sS'http/tests/media/text-served-as-text.html'
+p462
+(dp463
+g16
+S"text file served as 'text/plain'"
+p464
+ssg211
+g212
+sS'http/tests/media/video-cancel-load.html'
+p465
+(dp466
+g16
+S'Cancel loading a video file and access its properties afterwards.'
+p467
+ssS'media/unsupported-rtsp.html'
+p468
+(dp469
+g16
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p470
+ssS'media/media-controls-clone.html'
+p471
+(dp472
+g16
+S'<video controls id=v></video><audio controls id=a></audio>'
+p473
+ssS'media/broken-video.html'
+p474
+(dp475
+g16
+S'Test that QuickTime file with broken content generates an error.'
+p476
+ssS'media/video-plays-past-end-of-test.html'
+p477
+(dp478
+g16
+g84
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p479
+(dp480
+g16
+S'WebGL Origin Restrictions Conformance Tests'
+p481
+ssS'media/video-replaces-poster.html'
+p482
+(dp483
+g16
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p484
+ssS'media/video-autoplay.html'
+p485
+(dp486
+g16
+g84
+ssS'media/video-set-rate-from-pause.html'
+p487
+(dp488
+g16
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p489
+ssg198
+g199
+sg229
+g230
+sS'media/video-src-remove.html'
+p490
+(dp491
+g16
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p492
+ssS'media/csp-blocks-video.html'
+p493
+(dp494
+g16
+S"This test passes if it doesn't alert failure."
+p495
+ssS'media/controls-drag-timebar.html'
+p496
+(dp497
+g16
+S'Test that dragging the timebar thumb causes seeks.'
+p498
+ssg232
+g233
+sS'media/audio-constructor-preload.html'
+p499
+(dp500
+g16
+S"Test that Audio() sets 'preload' attribute."
+p501
+ssS'media/video-poster-delayed.html'
+p502
+(dp503
+g16
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p504
+ssS'media/adopt-node-crash.html'
+p505
+(dp506
+g16
+S"Tests that we don't crash when moving a video element to a new document."
+p507
+ssS'media/media-initialTime.html'
+p508
+(dp509
+g16
+S"Test the, so far unused, 'initialTime' attribute."
+p510
+ssS'media/video-playbackrate.html'
+p511
+(dp512
+g16
+S'test playbackRate and defaultPlaybackRate'
+p513
+ssS'media/video-muted.html'
+p514
+(dp515
+g16
+S"Test 'muted' attribute"
+p516
+ssg241
+g242
+sS'media/video-src-change.html'
+p517
+(dp518
+g16
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p519
+ssS'compositing/overflow/overflow-compositing-descendant.html'
+p520
+(dp521
+g16
+S'You should see a green box under the video. If you see red, the test failed.'
+p522
+ssg247
+g248
+sS'media/video-play-pause-exception.html'
+p523
+(dp524
+g16
+S'Video has no src. Test that the playing event is not dispatched.'
+p525
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p526
+(dp527
+g16
+g84
+ssS'media/audio-play-event.html'
+p528
+(dp529
+g16
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p530
+ssS'media/before-load-member-access.html'
+p531
+(dp532
+g16
+S'Test that accessing member of a non loaded video works.'
+p533
+ssS'media/video-dom-src.html'
+p534
+(dp535
+g16
+g84
+ssg135
+g136
+sS'media/audio-repaint.html'
+p536
+(dp537
+g8
+(lp538
+(dp539
+g366
+I01
+sg48
+I01
+sg23
+(lp540
+S'BUGWK65203'
+p541
+asg13
+S' These should be rebaselined after the patch lands, as we are now drawing all text with skia (instead of gdi) and in these cases, we have differences in antialiasing (drt specific) or in fractional-baselines (gdi rounds in src space, skia rounds in devices space '
+p542
+sasg16
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p543
+ssS'media/audio-controls-rendering.html'
+p544
+(dp545
+g16
+S'Test controls placement.'
+p546
+ssg220
+g221
+sS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p547
+(dp548
+g16
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p549
+ssS'media/invalid-media-url-crash.html'
+p550
+(dp551
+g16
+S'Tests that invalid media src url does not result in crash.'
+p552
+ssS'media/video-empty-source.html'
+p553
+(dp554
+g16
+S'Slider drawing with no source. The controls should render correctly.'
+p555
+ssg98
+g99
+sS'media/video-poster.html'
+p556
+(dp557
+g16
+S'Test &lt;video&gt; element with and without a poster.'
+p558
+ssS'media/media-document-audio-size.html'
+p559
+(dp560
+g16
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p561
+ssS'media/video-zoom.html'
+p562
+(dp563
+g16
+S'150% zoom, with width and height attributes'
+p564
+ssS'http/tests/appcache/video.html'
+p565
+(dp566
+g16
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p567
+ssg127
+g128
+sS'media/video-dom-autoplay.html'
+p568
+(dp569
+g16
+g84
+ssS'media/media-ended.html'
+p570
+(dp571
+g16
+S'<b>Test ended by:</b>'
+p572
+ssS'media/video-no-autoplay.html'
+p573
+(dp574
+g16
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p575
+ssg130
+g131
+sS'media/video-append-source.html'
+p576
+(dp577
+g16
+g84
+ssg138
+g139
+sS'http/tests/media/pdf-served-as-pdf.html'
+p578
+(dp579
+g16
+S"PDF file served as 'application/pdf'"
+p580
+ssS'media/video-play-empty-events.html'
+p581
+(dp582
+g16
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p583
+ssg146
+g147
+sS'media/audio-only-video-intrinsic-size.html'
+p584
+(dp585
+g16
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p586
+ssg141
+g142
+sS'http/tests/media/video-error-abort.html'
+p587
+(dp588
+g16
+S"'abort' event test"
+p589
+ssS'media/audio-delete-while-slider-thumb-clicked.html'
+p590
+(dp591
+g16
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p592
+ssS'media/media-can-play-ogg.html'
+p593
+(dp594
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p595
+ssg159
+g160
+sS'media/video-currentTime-set2.html'
+p596
+(dp597
+g16
+g84
+ssS'media/video-seekable.html'
+p598
+(dp599
+g16
+g84
+ssS'fast/dom/beforeload/video-before-load.html'
+p600
+(dp601
+g16
+g84
+ssS'media/video-played-reset.html'
+p602
+(dp603
+g16
+S"Test of the media element 'played' attribute"
+p604
+ssg177
+g178
+sS'compositing/self-painting-layers2.html'
+p605
+(dp606
+g16
+S'This test should not assert in debug builds.'
+p607
+ssg165
+g166
+sS'media/controls-right-click-on-timebar.html'
+p608
+(dp609
+g16
+S'Test that right clicking on the timebar does not cause a seek.'
+p610
+ssS'media/video-dom-preload.html'
+p611
+(dp612
+g16
+S'consoleWrite("++ Test default attribute value");'
+p613
+ssS'media/video-size.html'
+p614
+(dp615
+g16
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p616
+ssS'media/video-load-preload-none.html'
+p617
+(dp618
+g16
+S'Test that an explicit load() to a media element whose preload is set to "none" still loads the video.'
+p619
+ssS'media/video-delay-load-event.html'
+p620
+(dp621
+g8
+(lp622
+(dp623
+g52
+I01
+sg23
+(lp624
+S'BUGWK64003'
+p625
+asg13
+S' Started around WebKit r90233:r90242'
+p626
+sg83
+I01
+sg69
+I01
+sg351
+I01
+sasg16
+S"Test the document's load event is delayed until a movie's meta data is available."
+p627
+ssS'media/fallback.html'
+p628
+(dp629
+g16
+S'Test that fallback content is not rendered'
+p630
+ssS'media/video-layer-crash.html'
+p631
+(dp632
+g8
+(lp633
+(dp634
+g366
+I01
+sg48
+I01
+sg23
+(lp635
+S'BUGWK66437'
+p636
+asg13
+g354
+sg83
+I01
+sg53
+I01
+sasg16
+S'Test dynamic removal of transformed and reflected video'
+p637
+ssS'fast/layers/video-layer.html'
+p638
+(dp639
+g16
+S'Video element gets layer'
+p640
+ssS'media/controls-strict.html'
+p641
+(dp642
+g16
+S'Drawing the controls in strict mode.'
+p643
+ssS'media/remove-from-document.html'
+p644
+(dp645
+g16
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p646
+ssS'http/tests/media/remove-while-loading.html'
+p647
+(dp648
+g16
+S'Test that removing a media element from the tree while loading does not crash.'
+p649
+ssS'media/video-controls-transformed.html'
+p650
+(dp651
+g16
+S'This test only runs in DRT!'
+p652
+ssS'compositing/video/video-poster.html'
+p653
+(dp654
+g16
+S'Video with poster'
+p655
+ssS'media/video-display-toggle.html'
+p656
+(dp657
+g16
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p658
+ssS'media/video-seek-no-src-exception.html'
+p659
+(dp660
+g16
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p661
+ssS'media/audio-constructor-src.html'
+p662
+(dp663
+g16
+S'Test that Audio("url") constructor loads the specified resource.'
+p664
+ssS'compositing/geometry/clipped-video-controller.html'
+p665
+(dp666
+g16
+S'Clipped Video'
+p667
+ssg238
+g239
+sS'media/video-preload.html'
+p668
+(dp669
+g16
+S"Test to see if media loads automatically when 'preload' is specified."
+p670
+ssS'http/tests/media/video-load-twice.html'
+p671
+(dp672
+g16
+g84
+ssS'http/tests/media/video-cookie.html'
+p673
+(dp674
+g16
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p675
+ssS'media/video-source.html'
+p676
+(dp677
+g16
+g84
+ssS'media/video-seek-past-end-playing.html'
+p678
+(dp679
+g16
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p680
+ssS'media/video-currentTime-delay.html'
+p681
+(dp682
+g16
+S'Test a delay in playing the movie results in a canPlay event.'
+p683
+ssS'http/tests/media/reload-after-dialog.html'
+p684
+(dp685
+g16
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p686
+ssg217
+g218
+sS'media/media-constants.html'
+p687
+(dp688
+g16
+S'Test HTMLMediaElement and MediaError constants.'
+p689
+ssS'media/media-controls-invalid-url.html'
+p690
+(dp691
+g16
+S'This tests that media element controls are reset to their default state when the src is changed to an invalid url.'
+p692
+ssS'media/video-volume.html'
+p693
+(dp694
+g16
+S"Test 'volume' attribute"
+p695
+ssS'media/video-src-source.html'
+p696
+(dp697
+g16
+g84
+ssS'media/video-buffered.html'
+p698
+(dp699
+g16
+g84
+ssg64
+g65
+sS'media/video-source-load.html'
+p700
+(dp701
+g16
+S'Test that the resource selection algorithm is restarted when load() is called, and that all &lt;source&gt; elements are reconsidered.'
+p702
+ssg76
+g77
+sS'media/video-canvas-source.html'
+p703
+(dp704
+g16
+S'Drawing to canvas using video with source element does not taint canvas'
+p705
+ssS'media/video-controls-no-scripting.html'
+p706
+(dp707
+g16
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p708
+ssS'media/video-poster-scale.html'
+p709
+(dp710
+g16
+S"'poster' aspect ratio test"
+p711
+ssS'media/video-seek-by-small-increment.html'
+p712
+(dp713
+g16
+S'Test seeking by very small increments.'
+p714
+ssg103
+g104
+sS'media/video-controls-with-mutation-event-handler.html'
+p715
+(dp716
+g16
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p717
+ssS'media/video-zoom-controls.html'
+p718
+(dp719
+g8
+(lp720
+(dp721
+g52
+I01
+sg23
+(lp722
+S'BUGWK67913'
+p723
+asg13
+S' Failing after r94912.'
+p724
+sasg16
+S'Zoomed video with controls.'
+p725
+ssS'media/video-loop.html'
+p726
+(dp727
+g8
+(lp728
+(dp729
+g366
+I01
+sg69
+I01
+sg23
+(lp730
+S'BUGCR59415'
+p731
+asg13
+S' BUGCR59415 : cannot repro the flakiness'
+p732
+sg15
+I01
+sg52
+I01
+sasg16
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p733
+ssS'http/tests/media/video-play-stall.html'
+p734
+(dp735
+g8
+(lp736
+(dp737
+g52
+I01
+sg23
+(lp738
+S'BUGCR73609'
+p739
+asg13
+S' canplaythrough event is sent too early.'
+p740
+sasg16
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p741
+ssS'media/video-seeking.html'
+p742
+(dp743
+g16
+S'Test that seeking attribute is true immediately after a seek,'
+p744
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p745
+(dp746
+g16
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p747
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p748
+(dp749
+g16
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p750
+ssg55
+g56
+sg162
+g163
+sS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p751
+(dp752
+g16
+g84
+ssS'compositing/reflections/load-video-in-reflection.html'
+p753
+(dp754
+g16
+S'You should see a reflected video below, rather than the red video background.'
+p755
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p756
+(dp757
+g16
+S'Video overlay'
+p758
+ssS'media/video-controls-rendering.html'
+p759
+(dp760
+g8
+(lp761
+(dp762
+g53
+I01
+sg48
+I01
+sg23
+(lp763
+S'BUGCR94409'
+p764
+asg13
+S' Flaky scrollbar issues'
+p765
+sS'LINUX'
+p766
+I01
+sasg16
+S'Test controls placement.'
+p767
+ssS'http/tests/media/video-served-as-text.html'
+p768
+(dp769
+g16
+S"media file served as 'text/plain'"
+p770
+ssS'media/video-pause-empty-events.html'
+p771
+(dp772
+g16
+S'Test that pause() from EMPTY network state triggers load()'
+p773
+ssg61
+g62
+sS'media/media-load-event.html'
+p774
+(dp775
+g16
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p776
+ssS'media/video-defaultmuted.html'
+p777
+(dp778
+g16
+S'consoleWrite("<br><br><b>*** Test <em>" + (defaultMuted ? "with" : "without") + "</em> \'muted\' content attribute</b><br>");'
+p779
+ssS'media/video-volume-slider.html'
+p780
+(dp781
+g16
+S'Test rendering of volume slider of video tag'
+p782
+ssS'media/video-seek-past-end-paused.html'
+p783
+(dp784
+g16
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p785
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p786
+(dp787
+g16
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p788
+ssS'media/remove-from-document-before-load.html'
+p789
+(dp790
+g16
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p791
+ssS'media/video-duration-known-after-eos.html'
+p792
+(dp793
+g16
+S'Tests that duration is known after playback ended.'
+p794
+ssS'http/tests/media/video-play-stall-before-meta-data.html'
+p795
+(dp796
+g16
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p797
+ssS'media/video-timeupdate-during-playback.html'
+p798
+(dp799
+g16
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p800
+ssS'media/video-single-valid-source.html'
+p801
+(dp802
+g16
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p803
+ssS'media/video-src-invalid-remove.html'
+p804
+(dp805
+g16
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p806
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p807
+(dp808
+g16
+S"This test passes if it doesn't alert failure."
+p809
+ssg235
+g236
+sg258
+g259
+sS'media/video-load-readyState.html'
+p810
+(dp811
+g16
+g84
+sssS'nonskip'
+p812
+(dp813
+g388
+g389
+sg726
+g727
+sg536
+g537
+sg734
+g735
+sg275
+g276
+sg362
+g363
+sg759
+g760
+sg620
+g621
+sg718
+g719
+sg631
+g632
+sg406
+g407
+sg347
+g348
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/test_data/base b/chromium/media/tools/layout_tests/test_data/base
new file mode 100644
index 00000000000..59795ca0413
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_data/base
@@ -0,0 +1,1877 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/video-does-not-loop.html'
+p6
+(dp7
+S'te_info'
+p8
+(lp9
+(dp10
+S'SKIP'
+p11
+I01
+sS'WONTFIX'
+p12
+I01
+sS'Comments'
+p13
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p14
+sS'TIMEOUT'
+p15
+I01
+sasS'desc'
+p16
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p17
+ssS'media/audio-delete-while-step-button-clicked.html'
+p18
+(dp19
+g8
+(lp20
+(dp21
+S'FAIL'
+p22
+I01
+sg11
+I01
+sS'Bugs'
+p23
+(lp24
+S'BUGCR25375'
+p25
+aS'BUGCR59399'
+p26
+asg13
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p27
+sasg16
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p28
+ssS'media/restore-from-page-cache.html'
+p29
+(dp30
+g8
+(lp31
+(dp32
+g11
+I01
+sg12
+I01
+sg13
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p33
+sg15
+I01
+sg23
+(lp34
+S'BUGCR19635'
+p35
+asasg16
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p36
+ssS'media/context-menu-actions.html'
+p37
+(dp38
+g8
+(lp39
+(dp40
+S'CRASH'
+p41
+I01
+sg11
+I01
+sg23
+(lp42
+S'BUGCR59665'
+p43
+aS'BUGWK45021'
+p44
+asg13
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p45
+sg15
+I01
+sS'PASS'
+p46
+I01
+sasg16
+S'Test the various actions available in the HTML5 media element context-menu.'
+p47
+ssS'media/track/track-webvtt-tc005-headercomment.html'
+p48
+(dp49
+g8
+(lp50
+(dp51
+g11
+I01
+sg13
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p52
+sg15
+I01
+sg23
+(lp53
+S'BUGWK43668'
+p54
+asasg16
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p55
+ssS'http/tests/media/video-cross-site.html'
+p56
+(dp57
+g8
+(lp58
+(dp59
+g11
+I01
+sg13
+S' QuickTime reference movies not supported.'
+p60
+sg15
+I01
+sg46
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'media file redirects to another site'
+p61
+ssS'media/audio-data-url.html'
+p62
+(dp63
+g8
+(lp64
+(dp65
+g11
+I01
+sg23
+(lp66
+S'BUGCR16779'
+p67
+asg13
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that audio element can use a data: url'
+p69
+ssS'media/video-canvas-alpha.html'
+p70
+(dp71
+g8
+(lp72
+(dp73
+g11
+I01
+sS'IMAGE'
+p74
+I01
+sg23
+(lp75
+S'BUGCR74979'
+p76
+asg13
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p77
+sS'MAC'
+p78
+I01
+sS'GPU'
+p79
+I01
+sasg16
+S'UNKNOWN'
+p80
+ssS'media/video-can-play-type.html'
+p81
+(dp82
+g8
+(lp83
+(dp84
+g11
+I01
+sg23
+(lp85
+S'BUGCR16779'
+p86
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p87
+ssS'media/media-captions.html'
+p88
+(dp89
+g8
+(lp90
+(dp91
+g11
+I01
+sg13
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p92
+sg15
+I01
+sg23
+(lp93
+S'BUGCR28301'
+p94
+asasg16
+S'Test media element close caption API.'
+p95
+ssS'media/video-size-intrinsic-scale.html'
+p96
+(dp97
+g8
+(lp98
+(dp99
+g11
+I01
+sg23
+(lp100
+S'BUGCR16779'
+p101
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'&lt;video&gt; element intrinsic size test'
+p102
+ssS'media/track/track-webvtt-tc011-blanklines.html'
+p103
+(dp104
+g8
+g50
+sg16
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p105
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p106
+(dp107
+g8
+g50
+sg16
+S'Tests cues that are temporally out of order (we allow this).'
+p108
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p109
+(dp110
+g8
+g50
+sg16
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p111
+ssS'media/media-can-play-mpeg-audio.html'
+p112
+(dp113
+g8
+(lp114
+(dp115
+g11
+I01
+sg12
+I01
+sg23
+(lp116
+S'BUGCR16779'
+p117
+asg13
+g68
+sS'TEXT'
+p118
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p119
+ssS'media/audio-mpeg4-supported.html'
+p120
+(dp121
+g8
+(lp122
+(dp123
+g11
+I01
+sg23
+(lp124
+S'BUGCR16779'
+p125
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that the audio element supports M4A files.'
+p126
+ssS'media/track/track-webvtt-tc004-magicheader.html'
+p127
+(dp128
+g8
+g50
+sg16
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p129
+ssS'media/media-fullscreen-not-in-document.html'
+p130
+(dp131
+g8
+(lp132
+(dp133
+g11
+I01
+sg13
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p134
+sg15
+I01
+sg23
+(lp135
+S'BUGCR16735'
+p136
+asasg16
+S'Test media element fullscreen API when an element is not in the DOM.'
+p137
+ssS'media/audio-mpeg-supported.html'
+p138
+(dp139
+g8
+(lp140
+(dp141
+g11
+I01
+sg23
+(lp142
+S'BUGCR16779'
+p143
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S'Test that the audio element supports MPEG files.'
+p144
+ssS'media/track/track-webvtt-tc003-newlines.html'
+p145
+(dp146
+g8
+g50
+sg16
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p147
+ssS'media/video-document-types.html'
+p148
+(dp149
+g8
+(lp150
+(dp151
+g11
+I01
+sg23
+(lp152
+S'BUGCR16779'
+p153
+asg13
+g68
+sg15
+I01
+sg22
+I01
+sg12
+I01
+sasg16
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p154
+ssS'media/track/track-webvtt-tc002-bom.html'
+p155
+(dp156
+g8
+g50
+sg16
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p157
+ssS'media/media-fullscreen-inline.html'
+p158
+(dp159
+g8
+(lp160
+(dp161
+g11
+I01
+sg13
+g134
+sg15
+I01
+sg23
+(lp162
+S'BUGCR16735'
+p163
+asasg16
+S'Test media element fullscreen API when an element is in the DOM.'
+p164
+ssS'media/track/track-webvtt-tc000-empty.html'
+p165
+(dp166
+g8
+g50
+sg16
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p167
+ssS'media/media-can-play-mpeg4-video.html'
+p168
+(dp169
+g8
+(lp170
+(dp171
+g11
+I01
+sg12
+I01
+sg23
+(lp172
+S'BUGWK45102'
+p173
+asg13
+g68
+sg118
+I01
+sasg16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p174
+ssS'compositing/video/video-background-color.html'
+p175
+(dp176
+g8
+(lp177
+(dp178
+g22
+I01
+sg11
+I01
+sg12
+I01
+sg23
+(lp179
+S'BUGWK55519'
+p180
+asg13
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p181
+sasg16
+S'Video with background color'
+p182
+ssS'media/track/track-webvtt-tc010-notimings.html'
+p183
+(dp184
+g8
+g50
+sg16
+S'Tests cue without timings are ignored.'
+p185
+ssS'media/video-timeupdate-reverse-play.html'
+p186
+(dp187
+g8
+(lp188
+(dp189
+g11
+I01
+sg13
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p190
+sg15
+I01
+sg23
+(lp191
+S'BUGCR33099'
+p192
+asasg16
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p193
+ssS'http/tests/media/video-buffered.html'
+p194
+(dp195
+g8
+(lp196
+(dp197
+g11
+I01
+sg23
+(lp198
+S'BUGCR49165'
+p199
+asg13
+S' video.buffered multiple TimeRanges support.'
+p200
+sg46
+I01
+sasg16
+g80
+ssS'media/track/track-webvtt-tc001-utf8.html'
+p201
+(dp202
+g8
+g50
+sg16
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p203
+ssS'media/track/track-webvtt-tc013-settings.html'
+p204
+(dp205
+g8
+g50
+sg16
+S'Tests WebVTT settings.'
+p206
+ssS'media/track/track-webvtt-tc007-cuenoid.html'
+p207
+(dp208
+g8
+g50
+sg16
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p209
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p210
+(dp211
+g8
+g50
+sg16
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p212
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p213
+(dp214
+g8
+g50
+sg16
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p215
+ssS'media/video-element-other-namespace-crash.html'
+p216
+(dp217
+g8
+(lp218
+(dp219
+g11
+I01
+sg12
+I01
+sg13
+g68
+sg15
+I01
+sg23
+(lp220
+S'BUGCR68289'
+p221
+asasg16
+g80
+ssS'media/video-reverse-play-duration.html'
+p222
+(dp223
+g8
+(lp224
+(dp225
+g11
+I01
+sg13
+g190
+sg15
+I01
+sg23
+(lp226
+S'BUGCR33099'
+p227
+asasg16
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p228
+sssS'whole'
+p229
+(dp230
+S'media/video-source-type.html'
+p231
+(dp232
+g16
+S'&lt;source&gt; @type attribute'
+p233
+ssS'media/media-startTime.html'
+p234
+(dp235
+g16
+S"Test the, so far unused, 'startTime' attribute."
+p236
+ssS'media/video-src-set.html'
+p237
+(dp238
+g16
+S'Test that setting src attribute triggers load'
+p239
+ssg18
+g19
+sS'media/video-played-ranges-1.html'
+p240
+(dp241
+g16
+S"Test of the media element 'played' attribute, ranges part 1."
+p242
+ssS'http/tests/media/video-play-stall-seek.html'
+p243
+(dp244
+g8
+(lp245
+(dp246
+g13
+S' Timing out.'
+p247
+sg15
+I01
+sg23
+(lp248
+S'BUGCR78376'
+p249
+asasg16
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p250
+ssg62
+g63
+sg81
+g82
+sg88
+g89
+sS'media/controls-after-reload.html'
+p251
+(dp252
+g16
+S'Making sure the controller looks ok after a second load().'
+p253
+ssS'http/tests/media/video-referer.html'
+p254
+(dp255
+g16
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p256
+ssS'media/video-source-removed.html'
+p257
+(dp258
+g16
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p259
+ssS'media/unsupported-tracks.html'
+p260
+(dp261
+g16
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p262
+ssg120
+g121
+sS'media/audio-no-installed-engines.html'
+p263
+(dp264
+g16
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p265
+ssg130
+g131
+sS'media/video-width-height.html'
+p266
+(dp267
+g16
+g80
+ssS'media/media-blocked-by-willsendrequest.html'
+p268
+(dp269
+g16
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p270
+ssS'media/video-error-does-not-exist.html'
+p271
+(dp272
+g16
+S'Test that the media element is in correct state after load fails.'
+p273
+ssS'media/video-play-pause-events.html'
+p274
+(dp275
+g16
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p276
+ssS'media/video-display-none-crash.html'
+p277
+(dp278
+g16
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p279
+ssS'media/video-src-plus-source.html'
+p280
+(dp281
+g16
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p282
+ssS'media/video-source-none-supported.html'
+p283
+(dp284
+g16
+S'no usable &lt;source&gt; test'
+p285
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p286
+(dp287
+g16
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p288
+ssg6
+g7
+sS'media/video-src.html'
+p289
+(dp290
+g16
+g80
+ssg175
+g176
+sS'media/video-src-invalid-poster.html'
+p291
+(dp292
+g16
+g80
+ssS'media/video-source-inserted.html'
+p293
+(dp294
+g16
+S'networkState after inserting &lt;source&gt; test'
+p295
+ssS'media/media-can-play-octet-stream.html'
+p296
+(dp297
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p298
+ssS'media/constructors.html'
+p299
+(dp300
+g16
+S'Test that media constructors behave consistently.'
+p301
+ssS'media/video-source-media.html'
+p302
+(dp303
+g16
+g80
+ssg194
+g195
+sS'media/video-aspect-ratio.html'
+p304
+(dp305
+g16
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p306
+ssg201
+g202
+sS'media/video-source-type-params.html'
+p307
+(dp308
+g16
+g80
+ssS'fast/canvas/webgl/context-lost.html'
+p309
+(dp310
+g16
+S'debug("Test valid context");'
+p311
+ssS'media/media-can-play-wav-audio.html'
+p312
+(dp313
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p314
+ssS'media/video-source-error.html'
+p315
+(dp316
+g8
+(lp317
+(dp318
+S'DEBUG'
+p319
+I01
+sg118
+I01
+sg23
+(lp320
+S'BUGWK66310'
+p321
+asg13
+S''
+p322
+sg46
+I01
+sasg16
+S'&lt;video&gt; and &lt;source&gt; error test'
+p323
+ssS'media/video-no-audio.html'
+p324
+(dp325
+g16
+S'Movie with no audio track. The volume button should not render.'
+p326
+ssS'media/svg-as-image-with-media-blocked.html'
+p327
+(dp328
+g16
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p329
+ssS'media/video-transformed.html'
+p330
+(dp331
+g16
+S'Test painting of transformed video'
+p332
+ssg207
+g208
+sg213
+g214
+sS'media/video-click-dblckick-standalone.html'
+p333
+(dp334
+g16
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p335
+ssS'media/video-pause-immediately.html'
+p336
+(dp337
+g16
+S'Test that pausing the media element has an immediate effect on the clock.'
+p338
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p339
+(dp340
+g16
+g80
+ssg222
+g223
+sS'http/tests/security/local-video-src-from-remote.html'
+p341
+(dp342
+g16
+S'This test only works in DRT'
+p343
+ssS'media/media-document-audio-repaint.html'
+p344
+(dp345
+g8
+(lp346
+(dp347
+g118
+I01
+sg74
+I01
+sg23
+(lp348
+S'BUGCR75354'
+p349
+aS'BUGWK55718'
+p350
+asg13
+S' This test needs completely new baselines.'
+p351
+sS'IMAGE+TEXT'
+p352
+I01
+sasg16
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p353
+ssS'media/video-controls-in-media-document.html'
+p354
+(dp355
+g16
+g80
+ssS'media/remove-from-document-no-load.html'
+p356
+(dp357
+g16
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p358
+ssS'media/video-currentTime.html'
+p359
+(dp360
+g16
+g80
+ssS'media/video-frame-accurate-seek.html'
+p361
+(dp362
+g8
+(lp363
+(dp364
+g74
+I01
+sg23
+(lp365
+S'BUGCR72223'
+p366
+asg13
+g322
+sg46
+I01
+sasg16
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p367
+ssg29
+g30
+sg37
+g38
+sS'media/video-load-networkState.html'
+p368
+(dp369
+g16
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p370
+ssg48
+g49
+sS'media/controls-css-overload.html'
+p371
+(dp372
+g16
+S"Testing that overloading some controls doesn't crash the browser"
+p373
+ssS'media/video-display-aspect-ratio.html'
+p374
+(dp375
+g16
+g80
+ssS'media/video-currentTime-set.html'
+p376
+(dp377
+g16
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p378
+ssS'media/media-blocked-by-beforeload.html'
+p379
+(dp380
+g8
+(lp381
+(dp382
+g118
+I01
+sg23
+(lp383
+S'BUGWK66310'
+p384
+asg13
+g322
+sg46
+I01
+sasg16
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p385
+ssg106
+g107
+sS'media/video-controls-visible-audio-only.html'
+p386
+(dp387
+g16
+S'This test only runs in DRT!'
+p388
+ssS'http/tests/media/video-play-progress.html'
+p389
+(dp390
+g16
+S'Test that at least one progress event is fired after starting to load the video.'
+p391
+ssg112
+g113
+sS'media/video-source-moved.html'
+p392
+(dp393
+g16
+S'moving &lt;source&gt; element test'
+p394
+ssS'http/tests/security/local-video-source-from-remote.html'
+p395
+(dp396
+g16
+S'This test only behaves correctly in DRT'
+p397
+ssS'media/video-src-none.html'
+p398
+(dp399
+g16
+g80
+ssS'media/video-controls-zoomed.html'
+p400
+(dp401
+g16
+S'This test only runs in DRT!'
+p402
+ssS'media/video-controls.html'
+p403
+(dp404
+g16
+S"Test 'controls' attribute"
+p405
+ssS'media/controls-without-preload.html'
+p406
+(dp407
+g16
+S'The controls should not depend on preload value.'
+p408
+ssS'media/video-played-collapse.html'
+p409
+(dp410
+g16
+S"Test of the media element 'played' attribute"
+p411
+ssS'compositing/self-painting-layers.html'
+p412
+(dp413
+g16
+S'Self painting layers'
+p414
+ssS'media/audio-controls-do-not-fade-out.html'
+p415
+(dp416
+g16
+S'This tests that audio controls do not fade out when the audio is playing.'
+p417
+ssg158
+g159
+sS'compositing/geometry/video-opacity-overlay.html'
+p418
+(dp419
+g16
+S'Video overlay'
+p420
+ssS'media/video-source-error-no-candidate.html'
+p421
+(dp422
+g16
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p423
+ssS'media/audio-constructor.html'
+p424
+(dp425
+g16
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p426
+ssS'media/controls-styling.html'
+p427
+(dp428
+g16
+S'The look of the controls should not change.'
+p429
+ssS'media/event-attributes.html'
+p430
+(dp431
+g16
+g80
+ssg183
+g184
+sg186
+g187
+sS'http/tests/media/text-served-as-text.html'
+p432
+(dp433
+g16
+S"text file served as 'text/plain'"
+p434
+ssS'http/tests/media/video-cancel-load.html'
+p435
+(dp436
+g16
+S'Cancel loading a video file and access its properties afterwards.'
+p437
+ssS'media/unsupported-rtsp.html'
+p438
+(dp439
+g16
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p440
+ssS'media/media-controls-clone.html'
+p441
+(dp442
+g16
+S'<video controls id=v></video><audio controls id=a></audio>'
+p443
+ssS'media/broken-video.html'
+p444
+(dp445
+g16
+S'Test that QuickTime file with broken content generates an error.'
+p446
+ssS'media/video-plays-past-end-of-test.html'
+p447
+(dp448
+g16
+g80
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p449
+(dp450
+g16
+S'WebGL Origin Restrictions Conformance Tests'
+p451
+ssS'media/video-replaces-poster.html'
+p452
+(dp453
+g16
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p454
+ssS'media/video-autoplay.html'
+p455
+(dp456
+g16
+g80
+ssS'media/video-set-rate-from-pause.html'
+p457
+(dp458
+g16
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p459
+ssS'media/video-src-remove.html'
+p460
+(dp461
+g16
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p462
+ssS'media/csp-blocks-video.html'
+p463
+(dp464
+g16
+S"This test passes if it doesn't alert failure."
+p465
+ssS'media/controls-drag-timebar.html'
+p466
+(dp467
+g16
+S'Test that dragging the timebar thumb causes seeks.'
+p468
+ssS'media/audio-constructor-preload.html'
+p469
+(dp470
+g16
+S"Test that Audio() sets 'preload' attribute."
+p471
+ssS'media/video-poster-delayed.html'
+p472
+(dp473
+g16
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p474
+ssS'media/adopt-node-crash.html'
+p475
+(dp476
+g16
+S"Tests that we don't crash when moving a video element to a new document."
+p477
+ssS'media/video-playbackrate.html'
+p478
+(dp479
+g16
+S'test playbackRate and defaultPlaybackRate'
+p480
+ssS'media/video-muted.html'
+p481
+(dp482
+g16
+S"Test 'muted' attribute"
+p483
+ssS'media/video-src-change.html'
+p484
+(dp485
+g16
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p486
+ssS'compositing/overflow/overflow-compositing-descendant.html'
+p487
+(dp488
+g16
+S'You should see a green box under the video. If you see red, the test failed.'
+p489
+ssg216
+g217
+sS'media/video-play-pause-exception.html'
+p490
+(dp491
+g16
+S'Video has no src. Test that the playing event is not dispatched.'
+p492
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p493
+(dp494
+g16
+g80
+ssS'media/audio-play-event.html'
+p495
+(dp496
+g16
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p497
+ssS'media/before-load-member-access.html'
+p498
+(dp499
+g16
+S'Test that accessing member of a non loaded video works.'
+p500
+ssS'media/video-dom-src.html'
+p501
+(dp502
+g16
+g80
+ssS'media/audio-repaint.html'
+p503
+(dp504
+g16
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p505
+ssS'media/audio-controls-rendering.html'
+p506
+(dp507
+g16
+S'Test controls placement.'
+p508
+ssg204
+g205
+sS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p509
+(dp510
+g16
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p511
+ssS'media/invalid-media-url-crash.html'
+p512
+(dp513
+g16
+S'Tests that invalid media src url does not result in crash.'
+p514
+ssS'media/video-empty-source.html'
+p515
+(dp516
+g16
+S'Slider drawing with no source. The controls should render correctly.'
+p517
+ssg96
+g97
+sS'media/video-poster.html'
+p518
+(dp519
+g16
+S'Test &lt;video&gt; element with and without a poster.'
+p520
+ssS'media/media-document-audio-size.html'
+p521
+(dp522
+g16
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p523
+ssS'media/video-zoom.html'
+p524
+(dp525
+g8
+(lp526
+(dp527
+g41
+I01
+sg74
+I01
+sg23
+(lp528
+S'BUGCR86714'
+p529
+asg13
+g322
+sg78
+I01
+sg79
+I01
+sasg16
+S'150% zoom, with width and height attributes'
+p530
+ssg103
+g104
+sS'http/tests/appcache/video.html'
+p531
+(dp532
+g16
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p533
+ssS'media/video-dom-autoplay.html'
+p534
+(dp535
+g16
+g80
+ssS'media/media-ended.html'
+p536
+(dp537
+g16
+S'<b>Test ended by:</b>'
+p538
+ssS'media/video-no-autoplay.html'
+p539
+(dp540
+g16
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p541
+ssg138
+g139
+sS'media/video-append-source.html'
+p542
+(dp543
+g16
+g80
+ssg145
+g146
+sS'http/tests/media/pdf-served-as-pdf.html'
+p544
+(dp545
+g16
+S"PDF file served as 'application/pdf'"
+p546
+ssS'media/video-play-empty-events.html'
+p547
+(dp548
+g16
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p549
+ssg155
+g156
+sS'media/audio-only-video-intrinsic-size.html'
+p550
+(dp551
+g16
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p552
+ssg148
+g149
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p553
+(dp554
+g16
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p555
+ssS'media/media-can-play-ogg.html'
+p556
+(dp557
+g16
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p558
+ssg127
+g128
+sg165
+g166
+sS'media/video-currentTime-set2.html'
+p559
+(dp560
+g16
+g80
+ssS'media/video-seekable.html'
+p561
+(dp562
+g16
+g80
+ssS'fast/dom/beforeload/video-before-load.html'
+p563
+(dp564
+g16
+g80
+ssS'media/video-played-reset.html'
+p565
+(dp566
+g16
+S"Test of the media element 'played' attribute"
+p567
+ssS'compositing/self-painting-layers2.html'
+p568
+(dp569
+g16
+S'This test should not assert in debug builds.'
+p570
+ssS'media/controls-right-click-on-timebar.html'
+p571
+(dp572
+g16
+S'Test that right clicking on the timebar does not cause a seek.'
+p573
+ssS'media/video-dom-preload.html'
+p574
+(dp575
+g16
+S'consoleWrite("++ Test default attribute value");'
+p576
+ssS'media/video-size.html'
+p577
+(dp578
+g16
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p579
+ssS'media/video-delay-load-event.html'
+p580
+(dp581
+g8
+(lp582
+(dp583
+g118
+I01
+sg23
+(lp584
+S'BUGWK64003'
+p585
+asg13
+S' Started around WebKit r90233:r90242'
+p586
+sg78
+I01
+sg46
+I01
+sg319
+I01
+sasg16
+S"Test the document's load event is delayed until a movie's meta data is available."
+p587
+ssS'media/fallback.html'
+p588
+(dp589
+g16
+S'Test that fallback content is not rendered'
+p590
+ssS'media/video-layer-crash.html'
+p591
+(dp592
+g16
+S'Test dynamic removal of transformed and reflected video'
+p593
+ssS'fast/layers/video-layer.html'
+p594
+(dp595
+g16
+S'Video element gets layer'
+p596
+ssS'media/controls-strict.html'
+p597
+(dp598
+g16
+S'Drawing the controls in strict mode.'
+p599
+ssS'media/remove-from-document.html'
+p600
+(dp601
+g16
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p602
+ssS'http/tests/media/remove-while-loading.html'
+p603
+(dp604
+g16
+S'Test that removing a media element from the tree while loading does not crash.'
+p605
+ssS'media/video-controls-transformed.html'
+p606
+(dp607
+g16
+S'This test only runs in DRT!'
+p608
+ssS'compositing/video/video-poster.html'
+p609
+(dp610
+g16
+S'Video with poster'
+p611
+ssS'media/video-display-toggle.html'
+p612
+(dp613
+g16
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p614
+ssS'media/video-seek-no-src-exception.html'
+p615
+(dp616
+g16
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p617
+ssS'media/audio-constructor-src.html'
+p618
+(dp619
+g16
+S'Test that Audio("url") constructor loads the specified resource.'
+p620
+ssS'compositing/geometry/clipped-video-controller.html'
+p621
+(dp622
+g16
+S'Clipped Video'
+p623
+ssS'media/video-preload.html'
+p624
+(dp625
+g16
+S"Test to see if media loads automatically when 'preload' is specified."
+p626
+ssS'http/tests/media/video-load-twice.html'
+p627
+(dp628
+g16
+g80
+ssS'http/tests/media/video-cookie.html'
+p629
+(dp630
+g16
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p631
+ssS'media/video-source.html'
+p632
+(dp633
+g16
+g80
+ssS'media/video-seek-past-end-playing.html'
+p634
+(dp635
+g16
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p636
+ssS'media/video-currentTime-delay.html'
+p637
+(dp638
+g16
+S'Test a delay in playing the movie results in a canPlay event.'
+p639
+ssS'http/tests/media/reload-after-dialog.html'
+p640
+(dp641
+g16
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p642
+ssS'media/media-constants.html'
+p643
+(dp644
+g16
+S'Test HTMLMediaElement and MediaError constants.'
+p645
+ssS'media/video-volume.html'
+p646
+(dp647
+g16
+S"Test 'volume' attribute"
+p648
+ssS'media/video-src-source.html'
+p649
+(dp650
+g16
+g80
+ssS'media/video-buffered.html'
+p651
+(dp652
+g16
+g80
+ssg56
+g57
+sg70
+g71
+sS'media/video-canvas-source.html'
+p653
+(dp654
+g16
+S'Drawing to canvas using video with source element does not taint canvas'
+p655
+ssS'media/video-controls-no-scripting.html'
+p656
+(dp657
+g16
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p658
+ssS'media/video-poster-scale.html'
+p659
+(dp660
+g16
+S"'poster' aspect ratio test"
+p661
+ssS'media/video-seek-by-small-increment.html'
+p662
+(dp663
+g16
+S'Test seeking by very small increments.'
+p664
+ssS'media/video-controls-with-mutation-event-handler.html'
+p665
+(dp666
+g16
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p667
+ssS'media/video-zoom-controls.html'
+p668
+(dp669
+g16
+S'Zoomed video with controls.'
+p670
+ssS'media/video-loop.html'
+p671
+(dp672
+g8
+(lp673
+(dp674
+S'WIN'
+p675
+I01
+sg46
+I01
+sg23
+(lp676
+S'BUGCR59415'
+p677
+asg13
+S' BUGCR59415 : cannot repro the flakiness'
+p678
+sg15
+I01
+sg118
+I01
+sasg16
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p679
+ssS'http/tests/media/video-play-stall.html'
+p680
+(dp681
+g8
+(lp682
+(dp683
+g118
+I01
+sg23
+(lp684
+S'BUGCR73609'
+p685
+asg13
+S' canplaythrough event is sent too early.'
+p686
+sasg16
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p687
+ssS'media/video-seeking.html'
+p688
+(dp689
+g16
+S'Test that seeking attribute is true immediately after a seek,'
+p690
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p691
+(dp692
+g16
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p693
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p694
+(dp695
+g16
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p696
+ssg168
+g169
+sS'media/media-controls-clone-crash.html'
+p697
+(dp698
+g16
+S'Test passes if it does not crash.'
+p699
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p700
+(dp701
+g16
+g80
+ssS'compositing/reflections/load-video-in-reflection.html'
+p702
+(dp703
+g16
+S'You should see a reflected video below, rather than the red video background.'
+p704
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p705
+(dp706
+g16
+S'Video overlay'
+p707
+ssS'media/video-controls-rendering.html'
+p708
+(dp709
+g8
+(lp710
+(dp711
+g74
+I01
+sS'LINUX'
+p712
+I01
+sg23
+(lp713
+S'BUGCR74102'
+p714
+asg13
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p715
+sg46
+I01
+sg79
+I01
+sa(dp716
+g41
+I01
+sg74
+I01
+sg23
+(lp717
+S'BUGCR86714'
+p718
+asg13
+g322
+sg78
+I01
+sg79
+I01
+sasg16
+S'Test controls placement.'
+p719
+ssS'http/tests/media/video-served-as-text.html'
+p720
+(dp721
+g16
+S"media file served as 'text/plain'"
+p722
+ssS'media/video-pause-empty-events.html'
+p723
+(dp724
+g16
+S'Test that pause() from EMPTY network state triggers load()'
+p725
+ssS'media/media-load-event.html'
+p726
+(dp727
+g16
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p728
+ssS'http/tests/media/video-error-abort.html'
+p729
+(dp730
+g16
+S"'abort' event test"
+p731
+ssS'media/video-volume-slider.html'
+p732
+(dp733
+g16
+S'Test rendering of volume slider of video tag'
+p734
+ssS'media/video-seek-past-end-paused.html'
+p735
+(dp736
+g16
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p737
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p738
+(dp739
+g16
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p740
+ssS'media/remove-from-document-before-load.html'
+p741
+(dp742
+g16
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p743
+ssg210
+g211
+sS'media/video-duration-known-after-eos.html'
+p744
+(dp745
+g16
+S'Tests that duration is known after playback ended.'
+p746
+ssg109
+g110
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p747
+(dp748
+g16
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p749
+ssS'media/video-timeupdate-during-playback.html'
+p750
+(dp751
+g16
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p752
+ssS'media/video-single-valid-source.html'
+p753
+(dp754
+g16
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p755
+ssS'media/video-src-invalid-remove.html'
+p756
+(dp757
+g16
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p758
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p759
+(dp760
+g16
+S"This test passes if it doesn't alert failure."
+p761
+ssS'media/video-load-readyState.html'
+p762
+(dp763
+g16
+g80
+sssS'nonskip'
+p764
+(dp765
+g344
+g345
+sg361
+g362
+sg708
+g709
+sg243
+g244
+sg524
+g525
+sg671
+g672
+sg680
+g681
+sg580
+g581
+sg379
+g380
+sg315
+g316
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/test_data/graph.html.bak b/chromium/media/tools/layout_tests/test_data/graph.html.bak
new file mode 100644
index 00000000000..a54aa4dccd1
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_data/graph.html.bak
@@ -0,0 +1,53 @@
+<html>
+ <head>
+ <script type='text/javascript' src='https://www.google.com/jsapi'></script>
+ <script type='text/javascript'>
+ google.load('visualization', '1', {'packages': ['annotatedtimeline']});
+ google.setOnLoadCallback(drawChart);
+ function drawChart() {
+ var data = new google.visualization.DataTable();
+ data.addColumn('date', 'Date');
+ data.addColumn('number', '#Tests');
+ data.addColumn('string', 'title1');
+ data.addColumn('string', 'text1');
+ data.addColumn('number', '#Skipped tests');
+ data.addColumn('string', 'title2');
+ data.addColumn('string', 'text2');
+ data.addColumn('number', '#Non-skipped tests');
+ data.addColumn('string', 'title2');
+ data.addColumn('string', 'text2');
+ data.addRows([
+ // insert 1
+ ]);
+ var data2 = new google.visualization.DataTable();
+ data2.addColumn('date', 'Date');
+ data2.addColumn('number', 'Passing Rate ' +
+ '(100-(#Non-skipped tests)/' +
+ '((#Tests)-(#Skipped tests))*100)');
+ data2.addColumn('string', 'title1');
+ data2.addColumn('string', 'text1');
+ data2.addRows([
+ // insert 2
+ ]);
+ var div1 = document.getElementById('chart_div');
+ var chart = new google.visualization.AnnotatedTimeLine(div1);
+ chart.draw(data, {displayAnnotations: true, allowHtml: true});
+
+ var div2 = document.getElementById('chart_div2');
+ var chart2 = new google.visualization.AnnotatedTimeLine(div2);
+ chart2.draw(data2, {displayAnnotations: true,
+ allowHtml: true,
+ scaleType: 'maximized'});
+ }
+ </script>
+ <title>Media Layout Test Analyzer Result</title>
+ </head>
+
+ <body>
+ <h2>Current Statistics</h2>
+ <h3 id='numbers'>Numbers</h3>
+ <div id='chart_div' style='width: 1400px; height: 480px;'></div>
+ <h3>Test passing rate</h3>
+ <div id='chart_div2' style='width: 1400px; height: 480px;'></div>
+ </body>
+</html>
diff --git a/chromium/media/tools/layout_tests/test_data/less b/chromium/media/tools/layout_tests/test_data/less
new file mode 100644
index 00000000000..526112c55ea
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_data/less
@@ -0,0 +1,1869 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/audio-delete-while-step-button-clicked.html'
+p6
+(dp7
+S'desc'
+p8
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p9
+sS'te_info'
+p10
+(lp11
+(dp12
+S'FAIL'
+p13
+I01
+sS'SKIP'
+p14
+I01
+sS'Bugs'
+p15
+(lp16
+S'BUGCR25375'
+p17
+aS'BUGCR59399'
+p18
+asS'Comments'
+p19
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p20
+sassS'media/restore-from-page-cache.html'
+p21
+(dp22
+g8
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p23
+sg10
+(lp24
+(dp25
+g14
+I01
+sS'WONTFIX'
+p26
+I01
+sS'TIMEOUT'
+p27
+I01
+sg19
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p28
+sg15
+(lp29
+S'BUGCR19635'
+p30
+asassS'media/context-menu-actions.html'
+p31
+(dp32
+g8
+S'Test the various actions available in the HTML5 media element context-menu.'
+p33
+sg10
+(lp34
+(dp35
+S'CRASH'
+p36
+I01
+sg14
+I01
+sg15
+(lp37
+S'BUGCR59665'
+p38
+aS'BUGWK45021'
+p39
+asg19
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p40
+sg27
+I01
+sS'PASS'
+p41
+I01
+sassS'media/track/track-webvtt-tc005-headercomment.html'
+p42
+(dp43
+g8
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p44
+sg10
+(lp45
+(dp46
+g14
+I01
+sg27
+I01
+sg19
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p47
+sg15
+(lp48
+S'BUGWK43668'
+p49
+asassS'http/tests/media/video-cross-site.html'
+p50
+(dp51
+g8
+S'media file redirects to another site'
+p52
+sg10
+(lp53
+(dp54
+g14
+I01
+sg19
+S' QuickTime reference movies not supported.'
+p55
+sg27
+I01
+sg41
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/audio-data-url.html'
+p56
+(dp57
+g8
+S'Test that audio element can use a data: url'
+p58
+sg10
+(lp59
+(dp60
+g14
+I01
+sg15
+(lp61
+S'BUGCR16779'
+p62
+asg19
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/video-canvas-alpha.html'
+p64
+(dp65
+g8
+S'UNKNOWN'
+p66
+sg10
+(lp67
+(dp68
+g14
+I01
+sS'IMAGE'
+p69
+I01
+sg15
+(lp70
+S'BUGCR74979'
+p71
+asg19
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p72
+sS'MAC'
+p73
+I01
+sS'GPU'
+p74
+I01
+sassS'media/video-can-play-type.html'
+p75
+(dp76
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p77
+sg10
+(lp78
+(dp79
+g14
+I01
+sg15
+(lp80
+S'BUGCR16779'
+p81
+asg19
+g63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/media-captions.html'
+p82
+(dp83
+g8
+S'Test media element close caption API.'
+p84
+sg10
+(lp85
+(dp86
+g14
+I01
+sg27
+I01
+sg19
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p87
+sg15
+(lp88
+S'BUGCR28301'
+p89
+asassS'media/media-can-play-mpeg-audio.html'
+p90
+(dp91
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p92
+sg10
+(lp93
+(dp94
+g14
+I01
+sg26
+I01
+sg15
+(lp95
+S'BUGCR16779'
+p96
+asg19
+g63
+sS'TEXT'
+p97
+I01
+sassS'media/track/track-webvtt-tc011-blanklines.html'
+p98
+(dp99
+g8
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p100
+sg10
+g45
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p101
+(dp102
+g8
+S'Tests cues that are temporally out of order (we allow this).'
+p103
+sg10
+g45
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p104
+(dp105
+g8
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p106
+sg10
+g45
+ssS'media/video-size-intrinsic-scale.html'
+p107
+(dp108
+g8
+S'&lt;video&gt; element intrinsic size test'
+p109
+sg10
+(lp110
+(dp111
+g14
+I01
+sg15
+(lp112
+S'BUGCR16779'
+p113
+asg19
+g63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/audio-mpeg4-supported.html'
+p114
+(dp115
+g8
+S'Test that the audio element supports M4A files.'
+p116
+sg10
+(lp117
+(dp118
+g14
+I01
+sg15
+(lp119
+S'BUGCR16779'
+p120
+asg19
+g63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/media-fullscreen-not-in-document.html'
+p121
+(dp122
+g8
+S'Test media element fullscreen API when an element is not in the DOM.'
+p123
+sg10
+(lp124
+(dp125
+g14
+I01
+sg27
+I01
+sg19
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p126
+sg15
+(lp127
+S'BUGCR16735'
+p128
+asassS'media/audio-mpeg-supported.html'
+p129
+(dp130
+g8
+S'Test that the audio element supports MPEG files.'
+p131
+sg10
+(lp132
+(dp133
+g14
+I01
+sg15
+(lp134
+S'BUGCR16779'
+p135
+asg19
+g63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/track/track-webvtt-tc003-newlines.html'
+p136
+(dp137
+g8
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p138
+sg10
+g45
+ssS'media/video-document-types.html'
+p139
+(dp140
+g8
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p141
+sg10
+(lp142
+(dp143
+g14
+I01
+sg15
+(lp144
+S'BUGCR16779'
+p145
+asg19
+g63
+sg27
+I01
+sg13
+I01
+sg26
+I01
+sassS'media/track/track-webvtt-tc002-bom.html'
+p146
+(dp147
+g8
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p148
+sg10
+g45
+ssS'media/video-does-not-loop.html'
+p149
+(dp150
+g8
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p151
+sg10
+(lp152
+(dp153
+g14
+I01
+sg26
+I01
+sg27
+I01
+sg19
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p154
+sassS'media/track/track-webvtt-tc000-empty.html'
+p155
+(dp156
+g8
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p157
+sg10
+g45
+ssS'media/media-can-play-mpeg4-video.html'
+p158
+(dp159
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p160
+sg10
+(lp161
+(dp162
+g14
+I01
+sg26
+I01
+sg15
+(lp163
+S'BUGWK45102'
+p164
+asg19
+g63
+sg97
+I01
+sassS'compositing/video/video-background-color.html'
+p165
+(dp166
+g8
+S'Video with background color'
+p167
+sg10
+(lp168
+(dp169
+g13
+I01
+sg14
+I01
+sg26
+I01
+sg15
+(lp170
+S'BUGWK55519'
+p171
+asg19
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p172
+sassS'media/track/track-webvtt-tc010-notimings.html'
+p173
+(dp174
+g8
+S'Tests cue without timings are ignored.'
+p175
+sg10
+g45
+ssS'media/video-timeupdate-reverse-play.html'
+p176
+(dp177
+g8
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p178
+sg10
+(lp179
+(dp180
+g14
+I01
+sg27
+I01
+sg19
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p181
+sg15
+(lp182
+S'BUGCR33099'
+p183
+asassS'http/tests/media/video-buffered.html'
+p184
+(dp185
+g8
+g66
+sg10
+(lp186
+(dp187
+g14
+I01
+sg15
+(lp188
+S'BUGCR49165'
+p189
+asg19
+S' video.buffered multiple TimeRanges support.'
+p190
+sg41
+I01
+sassS'media/track/track-webvtt-tc001-utf8.html'
+p191
+(dp192
+g8
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p193
+sg10
+g45
+ssS'media/track/track-webvtt-tc013-settings.html'
+p194
+(dp195
+g8
+S'Tests WebVTT settings.'
+p196
+sg10
+g45
+ssS'media/media-fullscreen-inline.html'
+p197
+(dp198
+g8
+S'Test media element fullscreen API when an element is in the DOM.'
+p199
+sg10
+(lp200
+(dp201
+g14
+I01
+sg27
+I01
+sg19
+g126
+sg15
+(lp202
+S'BUGCR16735'
+p203
+asassS'media/track/track-webvtt-tc007-cuenoid.html'
+p204
+(dp205
+g8
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p206
+sg10
+g45
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p207
+(dp208
+g8
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p209
+sg10
+g45
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p210
+(dp211
+g8
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p212
+sg10
+g45
+ssS'media/video-element-other-namespace-crash.html'
+p213
+(dp214
+g8
+g66
+sg10
+(lp215
+(dp216
+g14
+I01
+sg26
+I01
+sg27
+I01
+sg19
+g63
+sg15
+(lp217
+S'BUGCR68289'
+p218
+asassS'media/video-reverse-play-duration.html'
+p219
+(dp220
+g8
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p221
+sg10
+(lp222
+(dp223
+g14
+I01
+sg27
+I01
+sg19
+g181
+sg15
+(lp224
+S'BUGCR33099'
+p225
+asasssS'whole'
+p226
+(dp227
+S'media/media-startTime.html'
+p228
+(dp229
+g8
+S"Test the, so far unused, 'startTime' attribute."
+p230
+ssS'media/video-src-set.html'
+p231
+(dp232
+g8
+S'Test that setting src attribute triggers load'
+p233
+ssg6
+g7
+sS'media/video-played-ranges-1.html'
+p234
+(dp235
+g8
+S"Test of the media element 'played' attribute, ranges part 1."
+p236
+ssS'media/video-layer-crash.html'
+p237
+(dp238
+g8
+S'Test dynamic removal of transformed and reflected video'
+p239
+ssS'http/tests/media/video-play-stall-seek.html'
+p240
+(dp241
+g8
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p242
+sg10
+(lp243
+(dp244
+g27
+I01
+sg19
+S' Timing out.'
+p245
+sg15
+(lp246
+S'BUGCR78376'
+p247
+asassg56
+g57
+sg75
+g76
+sg82
+g83
+sS'http/tests/media/video-referer.html'
+p248
+(dp249
+g8
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p250
+ssS'media/video-source-removed.html'
+p251
+(dp252
+g8
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p253
+ssS'media/unsupported-tracks.html'
+p254
+(dp255
+g8
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p256
+ssg114
+g115
+sS'media/audio-no-installed-engines.html'
+p257
+(dp258
+g8
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p259
+ssg121
+g122
+sS'media/video-dom-src.html'
+p260
+(dp261
+g8
+g66
+ssS'media/media-blocked-by-willsendrequest.html'
+p262
+(dp263
+g8
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p264
+ssS'media/video-error-does-not-exist.html'
+p265
+(dp266
+g8
+S'Test that the media element is in correct state after load fails.'
+p267
+ssS'media/video-play-pause-events.html'
+p268
+(dp269
+g8
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p270
+ssS'media/video-display-none-crash.html'
+p271
+(dp272
+g8
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p273
+ssS'media/video-src-plus-source.html'
+p274
+(dp275
+g8
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p276
+ssS'media/video-source-none-supported.html'
+p277
+(dp278
+g8
+S'no usable &lt;source&gt; test'
+p279
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p280
+(dp281
+g8
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p282
+ssg149
+g150
+sS'media/video-src.html'
+p283
+(dp284
+g8
+g66
+ssS'media/audio-controls-rendering.html'
+p285
+(dp286
+g8
+S'Test controls placement.'
+p287
+ssg165
+g166
+sS'media/video-source-inserted.html'
+p288
+(dp289
+g8
+S'networkState after inserting &lt;source&gt; test'
+p290
+ssS'media/media-can-play-octet-stream.html'
+p291
+(dp292
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p293
+ssS'media/constructors.html'
+p294
+(dp295
+g8
+S'Test that media constructors behave consistently.'
+p296
+ssS'media/video-source-media.html'
+p297
+(dp298
+g8
+g66
+ssg184
+g185
+sS'http/tests/security/local-video-source-from-remote.html'
+p299
+(dp300
+g8
+S'This test only behaves correctly in DRT'
+p301
+ssg191
+g192
+sS'media/video-source-type-params.html'
+p302
+(dp303
+g8
+g66
+ssS'fast/canvas/webgl/context-lost.html'
+p304
+(dp305
+g8
+S'debug("Test valid context");'
+p306
+ssS'media/media-can-play-wav-audio.html'
+p307
+(dp308
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p309
+ssS'media/video-source-error.html'
+p310
+(dp311
+g8
+S'&lt;video&gt; and &lt;source&gt; error test'
+p312
+sg10
+(lp313
+(dp314
+S'DEBUG'
+p315
+I01
+sg97
+I01
+sg15
+(lp316
+S'BUGWK66310'
+p317
+asg19
+S''
+p318
+sg41
+I01
+sassS'media/video-no-audio.html'
+p319
+(dp320
+g8
+S'Movie with no audio track. The volume button should not render.'
+p321
+ssS'media/svg-as-image-with-media-blocked.html'
+p322
+(dp323
+g8
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p324
+ssg204
+g205
+sg104
+g105
+sS'media/video-click-dblckick-standalone.html'
+p325
+(dp326
+g8
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p327
+ssS'media/video-pause-immediately.html'
+p328
+(dp329
+g8
+S'Test that pausing the media element has an immediate effect on the clock.'
+p330
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p331
+(dp332
+g8
+g66
+ssg219
+g220
+sS'http/tests/security/local-video-src-from-remote.html'
+p333
+(dp334
+g8
+S'This test only works in DRT'
+p335
+ssg197
+g198
+sS'media/video-controls-in-media-document.html'
+p336
+(dp337
+g8
+g66
+ssS'media/remove-from-document-no-load.html'
+p338
+(dp339
+g8
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p340
+ssS'media/video-currentTime.html'
+p341
+(dp342
+g8
+g66
+ssS'media/video-frame-accurate-seek.html'
+p343
+(dp344
+g8
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p345
+sg10
+(lp346
+(dp347
+g69
+I01
+sg15
+(lp348
+S'BUGCR72223'
+p349
+asg19
+g318
+sg41
+I01
+sassg21
+g22
+sg31
+g32
+sS'media/media-controls-clone-crash.html'
+p350
+(dp351
+g8
+S'Test passes if it does not crash.'
+p352
+ssg42
+g43
+sS'media/controls-css-overload.html'
+p353
+(dp354
+g8
+S"Testing that overloading some controls doesn't crash the browser"
+p355
+ssS'media/video-display-aspect-ratio.html'
+p356
+(dp357
+g8
+g66
+ssS'media/video-currentTime-set.html'
+p358
+(dp359
+g8
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p360
+ssS'media/media-blocked-by-beforeload.html'
+p361
+(dp362
+g8
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p363
+sg10
+(lp364
+(dp365
+g97
+I01
+sg15
+(lp366
+S'BUGWK66310'
+p367
+asg19
+g318
+sg41
+I01
+sassg101
+g102
+sS'media/video-controls-visible-audio-only.html'
+p368
+(dp369
+g8
+S'This test only runs in DRT!'
+p370
+ssS'http/tests/media/video-play-progress.html'
+p371
+(dp372
+g8
+S'Test that at least one progress event is fired after starting to load the video.'
+p373
+ssg107
+g108
+sS'media/video-source-moved.html'
+p374
+(dp375
+g8
+S'moving &lt;source&gt; element test'
+p376
+ssg98
+g99
+sS'media/video-src-none.html'
+p377
+(dp378
+g8
+g66
+ssS'media/video-controls-zoomed.html'
+p379
+(dp380
+g8
+S'This test only runs in DRT!'
+p381
+ssS'media/video-controls.html'
+p382
+(dp383
+g8
+S"Test 'controls' attribute"
+p384
+ssS'media/controls-without-preload.html'
+p385
+(dp386
+g8
+S'The controls should not depend on preload value.'
+p387
+ssS'media/video-played-collapse.html'
+p388
+(dp389
+g8
+S"Test of the media element 'played' attribute"
+p390
+ssS'compositing/self-painting-layers.html'
+p391
+(dp392
+g8
+S'Self painting layers'
+p393
+ssS'media/audio-controls-do-not-fade-out.html'
+p394
+(dp395
+g8
+S'This tests that audio controls do not fade out when the audio is playing.'
+p396
+ssS'media/media-document-audio-repaint.html'
+p397
+(dp398
+g8
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p399
+sg10
+(lp400
+(dp401
+g97
+I01
+sg69
+I01
+sg15
+(lp402
+S'BUGCR75354'
+p403
+aS'BUGWK55718'
+p404
+asg19
+S' This test needs completely new baselines.'
+p405
+sS'IMAGE+TEXT'
+p406
+I01
+sassS'compositing/geometry/video-opacity-overlay.html'
+p407
+(dp408
+g8
+S'Video overlay'
+p409
+ssS'media/video-source-error-no-candidate.html'
+p410
+(dp411
+g8
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p412
+ssS'media/audio-constructor.html'
+p413
+(dp414
+g8
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p415
+ssS'media/controls-styling.html'
+p416
+(dp417
+g8
+S'The look of the controls should not change.'
+p418
+ssS'media/video-buffered.html'
+p419
+(dp420
+g8
+g66
+ssS'media/event-attributes.html'
+p421
+(dp422
+g8
+g66
+ssg173
+g174
+sg176
+g177
+sS'http/tests/media/text-served-as-text.html'
+p423
+(dp424
+g8
+S"text file served as 'text/plain'"
+p425
+ssS'http/tests/media/video-cancel-load.html'
+p426
+(dp427
+g8
+S'Cancel loading a video file and access its properties afterwards.'
+p428
+ssS'media/unsupported-rtsp.html'
+p429
+(dp430
+g8
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p431
+ssS'media/media-controls-clone.html'
+p432
+(dp433
+g8
+S'<video controls id=v></video><audio controls id=a></audio>'
+p434
+ssS'media/broken-video.html'
+p435
+(dp436
+g8
+S'Test that QuickTime file with broken content generates an error.'
+p437
+ssS'media/video-plays-past-end-of-test.html'
+p438
+(dp439
+g8
+g66
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p440
+(dp441
+g8
+S'WebGL Origin Restrictions Conformance Tests'
+p442
+ssS'media/video-replaces-poster.html'
+p443
+(dp444
+g8
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p445
+ssS'media/video-autoplay.html'
+p446
+(dp447
+g8
+g66
+ssS'media/video-set-rate-from-pause.html'
+p448
+(dp449
+g8
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p450
+ssS'media/video-src-remove.html'
+p451
+(dp452
+g8
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p453
+ssS'media/csp-blocks-video.html'
+p454
+(dp455
+g8
+S"This test passes if it doesn't alert failure."
+p456
+ssS'media/controls-drag-timebar.html'
+p457
+(dp458
+g8
+S'Test that dragging the timebar thumb causes seeks.'
+p459
+ssS'media/audio-constructor-preload.html'
+p460
+(dp461
+g8
+S"Test that Audio() sets 'preload' attribute."
+p462
+ssS'media/video-src-invalid-poster.html'
+p463
+(dp464
+g8
+g66
+ssS'media/adopt-node-crash.html'
+p465
+(dp466
+g8
+S"Tests that we don't crash when moving a video element to a new document."
+p467
+ssS'media/video-playbackrate.html'
+p468
+(dp469
+g8
+S'test playbackRate and defaultPlaybackRate'
+p470
+ssS'media/video-muted.html'
+p471
+(dp472
+g8
+S"Test 'muted' attribute"
+p473
+ssS'media/video-src-change.html'
+p474
+(dp475
+g8
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p476
+ssg213
+g214
+sS'media/video-play-pause-exception.html'
+p477
+(dp478
+g8
+S'Video has no src. Test that the playing event is not dispatched.'
+p479
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p480
+(dp481
+g8
+g66
+ssS'media/audio-play-event.html'
+p482
+(dp483
+g8
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p484
+ssS'media/before-load-member-access.html'
+p485
+(dp486
+g8
+S'Test that accessing member of a non loaded video works.'
+p487
+ssS'media/video-width-height.html'
+p488
+(dp489
+g8
+g66
+ssS'media/audio-repaint.html'
+p490
+(dp491
+g8
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p492
+ssS'media/video-currentTime-delay.html'
+p493
+(dp494
+g8
+S'Test a delay in playing the movie results in a canPlay event.'
+p495
+ssS'media/video-aspect-ratio.html'
+p496
+(dp497
+g8
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p498
+ssS'media/video-transformed.html'
+p499
+(dp500
+g8
+S'Test painting of transformed video'
+p501
+ssS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p502
+(dp503
+g8
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p504
+ssS'media/invalid-media-url-crash.html'
+p505
+(dp506
+g8
+S'Tests that invalid media src url does not result in crash.'
+p507
+ssS'media/video-empty-source.html'
+p508
+(dp509
+g8
+S'Slider drawing with no source. The controls should render correctly.'
+p510
+ssg90
+g91
+sS'media/video-poster.html'
+p511
+(dp512
+g8
+S'Test &lt;video&gt; element with and without a poster.'
+p513
+ssS'media/media-document-audio-size.html'
+p514
+(dp515
+g8
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p516
+ssg129
+g130
+sS'compositing/overflow/overflow-compositing-descendant.html'
+p517
+(dp518
+g8
+S'You should see a green box under the video. If you see red, the test failed.'
+p519
+ssS'media/video-dom-autoplay.html'
+p520
+(dp521
+g8
+g66
+ssS'media/media-ended.html'
+p522
+(dp523
+g8
+S'<b>Test ended by:</b>'
+p524
+ssS'media/video-no-autoplay.html'
+p525
+(dp526
+g8
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p527
+ssS'media/video-zoom.html'
+p528
+(dp529
+g8
+S'150% zoom, with width and height attributes'
+p530
+sg10
+(lp531
+(dp532
+g36
+I01
+sg69
+I01
+sg15
+(lp533
+S'BUGCR86714'
+p534
+asg19
+g318
+sg73
+I01
+sg74
+I01
+sassS'media/video-append-source.html'
+p535
+(dp536
+g8
+g66
+ssg136
+g137
+sS'http/tests/media/pdf-served-as-pdf.html'
+p537
+(dp538
+g8
+S"PDF file served as 'application/pdf'"
+p539
+ssS'media/video-play-empty-events.html'
+p540
+(dp541
+g8
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p542
+ssg146
+g147
+sS'media/audio-only-video-intrinsic-size.html'
+p543
+(dp544
+g8
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p545
+ssg139
+g140
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p546
+(dp547
+g8
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p548
+ssS'media/media-can-play-ogg.html'
+p549
+(dp550
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p551
+ssS'media/track/track-webvtt-tc004-magicheader.html'
+p552
+(dp553
+g8
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p554
+sg10
+g45
+ssg155
+g156
+sS'media/video-currentTime-set2.html'
+p555
+(dp556
+g8
+g66
+ssS'media/video-seekable.html'
+p557
+(dp558
+g8
+g66
+ssS'fast/dom/beforeload/video-before-load.html'
+p559
+(dp560
+g8
+g66
+ssS'media/video-played-reset.html'
+p561
+(dp562
+g8
+S"Test of the media element 'played' attribute"
+p563
+ssS'compositing/self-painting-layers2.html'
+p564
+(dp565
+g8
+S'This test should not assert in debug builds.'
+p566
+ssS'media/controls-right-click-on-timebar.html'
+p567
+(dp568
+g8
+S'Test that right clicking on the timebar does not cause a seek.'
+p569
+ssS'media/video-dom-preload.html'
+p570
+(dp571
+g8
+S'consoleWrite("++ Test default attribute value");'
+p572
+ssS'media/video-size.html'
+p573
+(dp574
+g8
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p575
+ssS'media/video-delay-load-event.html'
+p576
+(dp577
+g8
+S"Test the document's load event is delayed until a movie's meta data is available."
+p578
+sg10
+(lp579
+(dp580
+g97
+I01
+sg15
+(lp581
+S'BUGWK64003'
+p582
+asg19
+S' Started around WebKit r90233:r90242'
+p583
+sg73
+I01
+sg41
+I01
+sg315
+I01
+sassS'media/fallback.html'
+p584
+(dp585
+g8
+S'Test that fallback content is not rendered'
+p586
+ssS'fast/layers/video-layer.html'
+p587
+(dp588
+g8
+S'Video element gets layer'
+p589
+ssS'media/controls-strict.html'
+p590
+(dp591
+g8
+S'Drawing the controls in strict mode.'
+p592
+ssS'media/remove-from-document.html'
+p593
+(dp594
+g8
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p595
+ssS'http/tests/media/remove-while-loading.html'
+p596
+(dp597
+g8
+S'Test that removing a media element from the tree while loading does not crash.'
+p598
+ssS'media/video-controls-transformed.html'
+p599
+(dp600
+g8
+S'This test only runs in DRT!'
+p601
+ssS'compositing/video/video-poster.html'
+p602
+(dp603
+g8
+S'Video with poster'
+p604
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p605
+(dp606
+g8
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p607
+ssS'media/video-display-toggle.html'
+p608
+(dp609
+g8
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p610
+ssS'media/video-seek-no-src-exception.html'
+p611
+(dp612
+g8
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p613
+ssS'media/audio-constructor-src.html'
+p614
+(dp615
+g8
+S'Test that Audio("url") constructor loads the specified resource.'
+p616
+ssS'compositing/geometry/clipped-video-controller.html'
+p617
+(dp618
+g8
+S'Clipped Video'
+p619
+ssS'media/video-preload.html'
+p620
+(dp621
+g8
+S"Test to see if media loads automatically when 'preload' is specified."
+p622
+ssS'http/tests/media/video-load-twice.html'
+p623
+(dp624
+g8
+g66
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p625
+(dp626
+g8
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p627
+ssS'media/video-seek-past-end-playing.html'
+p628
+(dp629
+g8
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p630
+ssS'media/video-source.html'
+p631
+(dp632
+g8
+g66
+ssS'http/tests/media/reload-after-dialog.html'
+p633
+(dp634
+g8
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p635
+ssS'media/media-constants.html'
+p636
+(dp637
+g8
+S'Test HTMLMediaElement and MediaError constants.'
+p638
+ssS'media/video-volume.html'
+p639
+(dp640
+g8
+S"Test 'volume' attribute"
+p641
+ssS'media/video-src-source.html'
+p642
+(dp643
+g8
+g66
+ssS'http/tests/appcache/video.html'
+p644
+(dp645
+g8
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p646
+ssg50
+g51
+sg64
+g65
+sS'media/video-canvas-source.html'
+p647
+(dp648
+g8
+S'Drawing to canvas using video with source element does not taint canvas'
+p649
+ssS'media/video-controls-no-scripting.html'
+p650
+(dp651
+g8
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p652
+ssS'media/video-poster-scale.html'
+p653
+(dp654
+g8
+S"'poster' aspect ratio test"
+p655
+ssS'media/video-seek-by-small-increment.html'
+p656
+(dp657
+g8
+S'Test seeking by very small increments.'
+p658
+ssS'media/video-controls-with-mutation-event-handler.html'
+p659
+(dp660
+g8
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p661
+ssS'media/video-zoom-controls.html'
+p662
+(dp663
+g8
+S'Zoomed video with controls.'
+p664
+ssS'media/video-loop.html'
+p665
+(dp666
+g8
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p667
+sg10
+(lp668
+(dp669
+S'WIN'
+p670
+I01
+sg41
+I01
+sg15
+(lp671
+S'BUGCR59415'
+p672
+asg19
+S' BUGCR59415 : cannot repro the flakiness'
+p673
+sg27
+I01
+sg97
+I01
+sassS'http/tests/media/video-play-stall.html'
+p674
+(dp675
+g8
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p676
+sg10
+(lp677
+(dp678
+g97
+I01
+sg15
+(lp679
+S'BUGCR73609'
+p680
+asg19
+S' canplaythrough event is sent too early.'
+p681
+sassS'media/video-seeking.html'
+p682
+(dp683
+g8
+S'Test that seeking attribute is true immediately after a seek,'
+p684
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p685
+(dp686
+g8
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p687
+ssS'media/controls-after-reload.html'
+p688
+(dp689
+g8
+S'Making sure the controller looks ok after a second load().'
+p690
+ssg158
+g159
+sS'media/video-load-networkState.html'
+p691
+(dp692
+g8
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p693
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p694
+(dp695
+g8
+g66
+ssS'compositing/reflections/load-video-in-reflection.html'
+p696
+(dp697
+g8
+S'You should see a reflected video below, rather than the red video background.'
+p698
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p699
+(dp700
+g8
+S'Video overlay'
+p701
+ssS'media/video-controls-rendering.html'
+p702
+(dp703
+g8
+S'Test controls placement.'
+p704
+sg10
+(lp705
+(dp706
+g69
+I01
+sS'LINUX'
+p707
+I01
+sg15
+(lp708
+S'BUGCR74102'
+p709
+asg19
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p710
+sg41
+I01
+sg74
+I01
+sa(dp711
+g36
+I01
+sg69
+I01
+sg15
+(lp712
+S'BUGCR86714'
+p713
+asg19
+g318
+sg73
+I01
+sg74
+I01
+sassS'http/tests/media/video-served-as-text.html'
+p714
+(dp715
+g8
+S"media file served as 'text/plain'"
+p716
+ssS'media/video-pause-empty-events.html'
+p717
+(dp718
+g8
+S'Test that pause() from EMPTY network state triggers load()'
+p719
+ssS'media/video-poster-delayed.html'
+p720
+(dp721
+g8
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p722
+ssS'media/media-load-event.html'
+p723
+(dp724
+g8
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p725
+ssS'http/tests/media/video-error-abort.html'
+p726
+(dp727
+g8
+S"'abort' event test"
+p728
+ssS'media/video-volume-slider.html'
+p729
+(dp730
+g8
+S'Test rendering of volume slider of video tag'
+p731
+ssS'media/video-seek-past-end-paused.html'
+p732
+(dp733
+g8
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p734
+ssS'http/tests/media/video-cookie.html'
+p735
+(dp736
+g8
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p737
+ssS'media/remove-from-document-before-load.html'
+p738
+(dp739
+g8
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p740
+ssg207
+g208
+sS'media/video-duration-known-after-eos.html'
+p741
+(dp742
+g8
+S'Tests that duration is known after playback ended.'
+p743
+ssg210
+g211
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p744
+(dp745
+g8
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p746
+ssS'media/video-timeupdate-during-playback.html'
+p747
+(dp748
+g8
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p749
+ssS'media/video-single-valid-source.html'
+p750
+(dp751
+g8
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p752
+ssS'media/video-src-invalid-remove.html'
+p753
+(dp754
+g8
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p755
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p756
+(dp757
+g8
+S"This test passes if it doesn't alert failure."
+p758
+ssg194
+g195
+sS'media/video-load-readyState.html'
+p759
+(dp760
+g8
+g66
+sssS'nonskip'
+p761
+(dp762
+g397
+g398
+sg343
+g344
+sg674
+g675
+sg240
+g241
+sg528
+g529
+sg665
+g666
+sg702
+g703
+sg576
+g577
+sg361
+g362
+sg310
+g311
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/test_data/more b/chromium/media/tools/layout_tests/test_data/more
new file mode 100644
index 00000000000..736dfb4505f
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_data/more
@@ -0,0 +1,1883 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/track/track-webvtt-tc004-magicheader.html'
+p6
+(dp7
+S'desc'
+p8
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p9
+sS'te_info'
+p10
+(lp11
+(dp12
+S'SKIP'
+p13
+I01
+sS'TIMEOUT'
+p14
+I01
+sS'Comments'
+p15
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p16
+sS'Bugs'
+p17
+(lp18
+S'BUGWK43668'
+p19
+asassS'media/audio-delete-while-step-button-clicked.html'
+p20
+(dp21
+g8
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p22
+sg10
+(lp23
+(dp24
+S'FAIL'
+p25
+I01
+sg13
+I01
+sg17
+(lp26
+S'BUGCR25375'
+p27
+aS'BUGCR59399'
+p28
+asg15
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p29
+sassS'media/restore-from-page-cache.html'
+p30
+(dp31
+g8
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p32
+sg10
+(lp33
+(dp34
+g13
+I01
+sS'WONTFIX'
+p35
+I01
+sg14
+I01
+sg15
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p36
+sg17
+(lp37
+S'BUGCR19635'
+p38
+asassS'media/context-menu-actions.html'
+p39
+(dp40
+g8
+S'Test the various actions available in the HTML5 media element context-menu.'
+p41
+sg10
+(lp42
+(dp43
+S'CRASH'
+p44
+I01
+sg13
+I01
+sg17
+(lp45
+S'BUGCR59665'
+p46
+aS'BUGWK45021'
+p47
+asg15
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p48
+sg14
+I01
+sS'PASS'
+p49
+I01
+sassS'media/track/track-webvtt-tc005-headercomment.html'
+p50
+(dp51
+g8
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p52
+sg10
+g11
+ssS'http/tests/media/video-cross-site.html'
+p53
+(dp54
+g8
+S'media file redirects to another site'
+p55
+sg10
+(lp56
+(dp57
+g13
+I01
+sg15
+S' QuickTime reference movies not supported.'
+p58
+sg14
+I01
+sg49
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-data-url.html'
+p59
+(dp60
+g8
+S'Test that audio element can use a data: url'
+p61
+sg10
+(lp62
+(dp63
+g13
+I01
+sg17
+(lp64
+S'BUGCR16779'
+p65
+asg15
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/video-canvas-alpha.html'
+p67
+(dp68
+g8
+S'UNKNOWN'
+p69
+sg10
+(lp70
+(dp71
+g13
+I01
+sS'IMAGE'
+p72
+I01
+sg17
+(lp73
+S'BUGCR74979'
+p74
+asg15
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p75
+sS'MAC'
+p76
+I01
+sS'GPU'
+p77
+I01
+sassS'add2.html'
+p78
+I01
+sS'media/video-can-play-type.html'
+p79
+(dp80
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p81
+sg10
+(lp82
+(dp83
+g13
+I01
+sg17
+(lp84
+S'BUGCR16779'
+p85
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-captions.html'
+p86
+(dp87
+g8
+S'Test media element close caption API.'
+p88
+sg10
+(lp89
+(dp90
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p91
+sg17
+(lp92
+S'BUGCR28301'
+p93
+asassS'media/media-can-play-mpeg-audio.html'
+p94
+(dp95
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p96
+sg10
+(lp97
+(dp98
+g13
+I01
+sg35
+I01
+sg17
+(lp99
+S'BUGCR16779'
+p100
+asg15
+g66
+sS'TEXT'
+p101
+I01
+sassS'media/track/track-webvtt-tc011-blanklines.html'
+p102
+(dp103
+g8
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p104
+sg10
+g11
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p105
+(dp106
+g8
+S'Tests cues that are temporally out of order (we allow this).'
+p107
+sg10
+g11
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p108
+(dp109
+g8
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p110
+sg10
+g11
+ssS'media/video-size-intrinsic-scale.html'
+p111
+(dp112
+g8
+S'&lt;video&gt; element intrinsic size test'
+p113
+sg10
+(lp114
+(dp115
+g13
+I01
+sg17
+(lp116
+S'BUGCR16779'
+p117
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-mpeg4-supported.html'
+p118
+(dp119
+g8
+S'Test that the audio element supports M4A files.'
+p120
+sg10
+(lp121
+(dp122
+g13
+I01
+sg17
+(lp123
+S'BUGCR16779'
+p124
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-fullscreen-not-in-document.html'
+p125
+(dp126
+g8
+S'Test media element fullscreen API when an element is not in the DOM.'
+p127
+sg10
+(lp128
+(dp129
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p130
+sg17
+(lp131
+S'BUGCR16735'
+p132
+asassS'media/audio-mpeg-supported.html'
+p133
+(dp134
+g8
+S'Test that the audio element supports MPEG files.'
+p135
+sg10
+(lp136
+(dp137
+g13
+I01
+sg17
+(lp138
+S'BUGCR16779'
+p139
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc003-newlines.html'
+p140
+(dp141
+g8
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p142
+sg10
+g11
+ssS'media/video-document-types.html'
+p143
+(dp144
+g8
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p145
+sg10
+(lp146
+(dp147
+g13
+I01
+sg17
+(lp148
+S'BUGCR16779'
+p149
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc002-bom.html'
+p150
+(dp151
+g8
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p152
+sg10
+g11
+ssS'media/video-does-not-loop.html'
+p153
+(dp154
+g8
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p155
+sg10
+(lp156
+(dp157
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p158
+sassS'media/track/track-webvtt-tc000-empty.html'
+p159
+(dp160
+g8
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p161
+sg10
+g11
+ssS'media/media-can-play-mpeg4-video.html'
+p162
+(dp163
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p164
+sg10
+(lp165
+(dp166
+g13
+I01
+sg35
+I01
+sg17
+(lp167
+S'BUGWK45102'
+p168
+asg15
+g66
+sg101
+I01
+sassS'compositing/video/video-background-color.html'
+p169
+(dp170
+g8
+S'Video with background color'
+p171
+sg10
+(lp172
+(dp173
+g25
+I01
+sg13
+I01
+sg35
+I01
+sg17
+(lp174
+S'BUGWK55519'
+p175
+asg15
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p176
+sassS'media/track/track-webvtt-tc010-notimings.html'
+p177
+(dp178
+g8
+S'Tests cue without timings are ignored.'
+p179
+sg10
+g11
+ssS'media/video-timeupdate-reverse-play.html'
+p180
+(dp181
+g8
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p182
+sg10
+(lp183
+(dp184
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p185
+sg17
+(lp186
+S'BUGCR33099'
+p187
+asassS'http/tests/media/video-buffered.html'
+p188
+(dp189
+g8
+g69
+sg10
+(lp190
+(dp191
+g13
+I01
+sg17
+(lp192
+S'BUGCR49165'
+p193
+asg15
+S' video.buffered multiple TimeRanges support.'
+p194
+sg49
+I01
+sassS'media/track/track-webvtt-tc001-utf8.html'
+p195
+(dp196
+g8
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p197
+sg10
+g11
+ssS'media/track/track-webvtt-tc013-settings.html'
+p198
+(dp199
+g8
+S'Tests WebVTT settings.'
+p200
+sg10
+g11
+ssS'media/media-fullscreen-inline.html'
+p201
+(dp202
+g8
+S'Test media element fullscreen API when an element is in the DOM.'
+p203
+sg10
+(lp204
+(dp205
+g13
+I01
+sg14
+I01
+sg15
+g130
+sg17
+(lp206
+S'BUGCR16735'
+p207
+asassS'media/track/track-webvtt-tc007-cuenoid.html'
+p208
+(dp209
+g8
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p210
+sg10
+g11
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p211
+(dp212
+g8
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p213
+sg10
+g11
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p214
+(dp215
+g8
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p216
+sg10
+g11
+ssS'media/video-element-other-namespace-crash.html'
+p217
+(dp218
+g8
+g69
+sg10
+(lp219
+(dp220
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+g66
+sg17
+(lp221
+S'BUGCR68289'
+p222
+asassS'media/video-reverse-play-duration.html'
+p223
+(dp224
+g8
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p225
+sg10
+(lp226
+(dp227
+g13
+I01
+sg14
+I01
+sg15
+g185
+sg17
+(lp228
+S'BUGCR33099'
+p229
+asasssS'whole'
+p230
+(dp231
+S'media/video-source-type.html'
+p232
+(dp233
+g8
+S'&lt;source&gt; @type attribute'
+p234
+ssS'media/media-startTime.html'
+p235
+(dp236
+g8
+S"Test the, so far unused, 'startTime' attribute."
+p237
+ssS'media/video-src-set.html'
+p238
+(dp239
+g8
+S'Test that setting src attribute triggers load'
+p240
+ssg20
+g21
+sS'media/video-played-ranges-1.html'
+p241
+(dp242
+g8
+S"Test of the media element 'played' attribute, ranges part 1."
+p243
+ssS'media/video-layer-crash.html'
+p244
+(dp245
+g8
+S'Test dynamic removal of transformed and reflected video'
+p246
+ssS'http/tests/media/video-play-stall-seek.html'
+p247
+(dp248
+g8
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p249
+sg10
+(lp250
+(dp251
+g14
+I01
+sg15
+S' Timing out.'
+p252
+sg17
+(lp253
+S'BUGCR78376'
+p254
+asassg59
+g60
+sg79
+g80
+sg86
+g87
+sS'http/tests/media/video-referer.html'
+p255
+(dp256
+g8
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p257
+ssS'media/video-source-removed.html'
+p258
+(dp259
+g8
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p260
+ssS'media/unsupported-tracks.html'
+p261
+(dp262
+g8
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p263
+ssg118
+g119
+sS'media/audio-no-installed-engines.html'
+p264
+(dp265
+g8
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p266
+ssg125
+g126
+sS'media/video-dom-src.html'
+p267
+(dp268
+g8
+g69
+ssS'media/media-blocked-by-willsendrequest.html'
+p269
+(dp270
+g8
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p271
+ssS'media/video-error-does-not-exist.html'
+p272
+(dp273
+g8
+S'Test that the media element is in correct state after load fails.'
+p274
+ssS'media/video-play-pause-events.html'
+p275
+(dp276
+g8
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p277
+ssS'media/video-display-none-crash.html'
+p278
+(dp279
+g8
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p280
+ssS'media/video-src-plus-source.html'
+p281
+(dp282
+g8
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p283
+ssS'media/video-source-none-supported.html'
+p284
+(dp285
+g8
+S'no usable &lt;source&gt; test'
+p286
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p287
+(dp288
+g8
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p289
+ssg153
+g154
+sS'media/video-src.html'
+p290
+(dp291
+g8
+g69
+ssS'media/audio-controls-rendering.html'
+p292
+(dp293
+g8
+S'Test controls placement.'
+p294
+ssg169
+g170
+sS'media/video-source-inserted.html'
+p295
+(dp296
+g8
+S'networkState after inserting &lt;source&gt; test'
+p297
+ssS'media/media-can-play-octet-stream.html'
+p298
+(dp299
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p300
+ssS'media/constructors.html'
+p301
+(dp302
+g8
+S'Test that media constructors behave consistently.'
+p303
+ssS'media/video-source-media.html'
+p304
+(dp305
+g8
+g69
+ssg188
+g189
+sS'http/tests/security/local-video-source-from-remote.html'
+p306
+(dp307
+g8
+S'This test only behaves correctly in DRT'
+p308
+ssg195
+g196
+sS'media/video-source-type-params.html'
+p309
+(dp310
+g8
+g69
+ssS'fast/canvas/webgl/context-lost.html'
+p311
+(dp312
+g8
+S'debug("Test valid context");'
+p313
+ssS'media/media-can-play-wav-audio.html'
+p314
+(dp315
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p316
+ssS'media/video-source-error.html'
+p317
+(dp318
+g8
+S'&lt;video&gt; and &lt;source&gt; error test'
+p319
+sg10
+(lp320
+(dp321
+S'DEBUG'
+p322
+I01
+sg101
+I01
+sg17
+(lp323
+S'BUGWK66310'
+p324
+asg15
+S''
+p325
+sg49
+I01
+sassS'media/video-no-audio.html'
+p326
+(dp327
+g8
+S'Movie with no audio track. The volume button should not render.'
+p328
+ssS'media/svg-as-image-with-media-blocked.html'
+p329
+(dp330
+g8
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p331
+ssg208
+g209
+sg108
+g109
+sS'media/video-click-dblckick-standalone.html'
+p332
+(dp333
+g8
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p334
+ssS'media/video-pause-immediately.html'
+p335
+(dp336
+g8
+S'Test that pausing the media element has an immediate effect on the clock.'
+p337
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p338
+(dp339
+g8
+g69
+ssg223
+g224
+sS'http/tests/security/local-video-src-from-remote.html'
+p340
+(dp341
+g8
+S'This test only works in DRT'
+p342
+ssg201
+g202
+sS'media/video-controls-in-media-document.html'
+p343
+(dp344
+g8
+g69
+ssS'media/remove-from-document-no-load.html'
+p345
+(dp346
+g8
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p347
+ssS'media/video-currentTime.html'
+p348
+(dp349
+g8
+g69
+ssS'media/video-frame-accurate-seek.html'
+p350
+(dp351
+g8
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p352
+sg10
+(lp353
+(dp354
+g72
+I01
+sg17
+(lp355
+S'BUGCR72223'
+p356
+asg15
+g325
+sg49
+I01
+sassg30
+g31
+sg39
+g40
+sS'media/media-controls-clone-crash.html'
+p357
+(dp358
+g8
+S'Test passes if it does not crash.'
+p359
+ssg50
+g51
+sS'media/controls-css-overload.html'
+p360
+(dp361
+g8
+S"Testing that overloading some controls doesn't crash the browser"
+p362
+ssS'media/video-display-aspect-ratio.html'
+p363
+(dp364
+g8
+g69
+ssS'media/video-currentTime-set.html'
+p365
+(dp366
+g8
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p367
+ssS'media/media-blocked-by-beforeload.html'
+p368
+(dp369
+g8
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p370
+sg10
+(lp371
+(dp372
+g101
+I01
+sg17
+(lp373
+S'BUGWK66310'
+p374
+asg15
+g325
+sg49
+I01
+sassg105
+g106
+sS'media/video-controls-visible-audio-only.html'
+p375
+(dp376
+g8
+S'This test only runs in DRT!'
+p377
+ssS'http/tests/media/video-play-progress.html'
+p378
+(dp379
+g8
+S'Test that at least one progress event is fired after starting to load the video.'
+p380
+ssg111
+g112
+sS'media/video-source-moved.html'
+p381
+(dp382
+g8
+S'moving &lt;source&gt; element test'
+p383
+ssg102
+g103
+sS'media/video-src-none.html'
+p384
+(dp385
+g8
+g69
+ssS'media/video-controls-zoomed.html'
+p386
+(dp387
+g8
+S'This test only runs in DRT!'
+p388
+ssS'media/video-controls.html'
+p389
+(dp390
+g8
+S"Test 'controls' attribute"
+p391
+ssS'media/controls-without-preload.html'
+p392
+(dp393
+g8
+S'The controls should not depend on preload value.'
+p394
+ssS'media/video-played-collapse.html'
+p395
+(dp396
+g8
+S"Test of the media element 'played' attribute"
+p397
+ssS'compositing/self-painting-layers.html'
+p398
+(dp399
+g8
+S'Self painting layers'
+p400
+ssS'media/audio-controls-do-not-fade-out.html'
+p401
+(dp402
+g8
+S'This tests that audio controls do not fade out when the audio is playing.'
+p403
+ssS'media/media-document-audio-repaint.html'
+p404
+(dp405
+g8
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p406
+sg10
+(lp407
+(dp408
+g101
+I01
+sg72
+I01
+sg17
+(lp409
+S'BUGCR75354'
+p410
+aS'BUGWK55718'
+p411
+asg15
+S' This test needs completely new baselines.'
+p412
+sS'IMAGE+TEXT'
+p413
+I01
+sassS'compositing/geometry/video-opacity-overlay.html'
+p414
+(dp415
+g8
+S'Video overlay'
+p416
+ssS'media/video-source-error-no-candidate.html'
+p417
+(dp418
+g8
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p419
+ssS'media/audio-constructor.html'
+p420
+(dp421
+g8
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p422
+ssS'media/controls-styling.html'
+p423
+(dp424
+g8
+S'The look of the controls should not change.'
+p425
+ssS'media/video-buffered.html'
+p426
+(dp427
+g8
+g69
+ssS'media/event-attributes.html'
+p428
+(dp429
+g8
+g69
+ssg177
+g178
+sg180
+g181
+sS'http/tests/media/text-served-as-text.html'
+p430
+(dp431
+g8
+S"text file served as 'text/plain'"
+p432
+ssS'http/tests/media/video-cancel-load.html'
+p433
+(dp434
+g8
+S'Cancel loading a video file and access its properties afterwards.'
+p435
+ssS'media/unsupported-rtsp.html'
+p436
+(dp437
+g8
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p438
+ssS'media/media-controls-clone.html'
+p439
+(dp440
+g8
+S'<video controls id=v></video><audio controls id=a></audio>'
+p441
+ssS'media/broken-video.html'
+p442
+(dp443
+g8
+S'Test that QuickTime file with broken content generates an error.'
+p444
+ssS'media/video-plays-past-end-of-test.html'
+p445
+(dp446
+g8
+g69
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p447
+(dp448
+g8
+S'WebGL Origin Restrictions Conformance Tests'
+p449
+ssS'media/video-replaces-poster.html'
+p450
+(dp451
+g8
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p452
+ssS'media/video-autoplay.html'
+p453
+(dp454
+g8
+g69
+ssS'media/video-set-rate-from-pause.html'
+p455
+(dp456
+g8
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p457
+ssS'media/video-src-remove.html'
+p458
+(dp459
+g8
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p460
+ssS'media/csp-blocks-video.html'
+p461
+(dp462
+g8
+S"This test passes if it doesn't alert failure."
+p463
+ssS'media/controls-drag-timebar.html'
+p464
+(dp465
+g8
+S'Test that dragging the timebar thumb causes seeks.'
+p466
+ssS'media/audio-constructor-preload.html'
+p467
+(dp468
+g8
+S"Test that Audio() sets 'preload' attribute."
+p469
+ssS'media/video-src-invalid-poster.html'
+p470
+(dp471
+g8
+g69
+ssS'media/adopt-node-crash.html'
+p472
+(dp473
+g8
+S"Tests that we don't crash when moving a video element to a new document."
+p474
+ssS'media/video-playbackrate.html'
+p475
+(dp476
+g8
+S'test playbackRate and defaultPlaybackRate'
+p477
+ssS'media/video-muted.html'
+p478
+(dp479
+g8
+S"Test 'muted' attribute"
+p480
+ssS'media/video-src-change.html'
+p481
+(dp482
+g8
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p483
+ssg217
+g218
+sS'media/video-play-pause-exception.html'
+p484
+(dp485
+g8
+S'Video has no src. Test that the playing event is not dispatched.'
+p486
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p487
+(dp488
+g8
+g69
+ssS'media/audio-play-event.html'
+p489
+(dp490
+g8
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p491
+ssS'media/before-load-member-access.html'
+p492
+(dp493
+g8
+S'Test that accessing member of a non loaded video works.'
+p494
+ssS'media/video-width-height.html'
+p495
+(dp496
+g8
+g69
+ssS'media/audio-repaint.html'
+p497
+(dp498
+g8
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p499
+ssS'media/video-currentTime-delay.html'
+p500
+(dp501
+g8
+S'Test a delay in playing the movie results in a canPlay event.'
+p502
+ssS'media/video-aspect-ratio.html'
+p503
+(dp504
+g8
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p505
+ssS'media/video-transformed.html'
+p506
+(dp507
+g8
+S'Test painting of transformed video'
+p508
+ssS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p509
+(dp510
+g8
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p511
+ssS'media/invalid-media-url-crash.html'
+p512
+(dp513
+g8
+S'Tests that invalid media src url does not result in crash.'
+p514
+ssS'media/video-empty-source.html'
+p515
+(dp516
+g8
+S'Slider drawing with no source. The controls should render correctly.'
+p517
+ssg94
+g95
+sS'media/video-poster.html'
+p518
+(dp519
+g8
+S'Test &lt;video&gt; element with and without a poster.'
+p520
+ssS'media/media-document-audio-size.html'
+p521
+(dp522
+g8
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p523
+ssg133
+g134
+sS'add1.html'
+p524
+I01
+sS'compositing/overflow/overflow-compositing-descendant.html'
+p525
+(dp526
+g8
+S'You should see a green box under the video. If you see red, the test failed.'
+p527
+ssS'media/video-dom-autoplay.html'
+p528
+(dp529
+g8
+g69
+ssS'media/media-ended.html'
+p530
+(dp531
+g8
+S'<b>Test ended by:</b>'
+p532
+ssS'media/video-no-autoplay.html'
+p533
+(dp534
+g8
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p535
+ssS'media/video-zoom.html'
+p536
+(dp537
+g8
+S'150% zoom, with width and height attributes'
+p538
+sg10
+(lp539
+(dp540
+g44
+I01
+sg72
+I01
+sg17
+(lp541
+S'BUGCR86714'
+p542
+asg15
+g325
+sg76
+I01
+sg77
+I01
+sassS'media/video-append-source.html'
+p543
+(dp544
+g8
+g69
+ssg140
+g141
+sS'http/tests/media/pdf-served-as-pdf.html'
+p545
+(dp546
+g8
+S"PDF file served as 'application/pdf'"
+p547
+ssS'media/video-play-empty-events.html'
+p548
+(dp549
+g8
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p550
+ssg150
+g151
+sS'media/audio-only-video-intrinsic-size.html'
+p551
+(dp552
+g8
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p553
+ssg143
+g144
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p554
+(dp555
+g8
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p556
+ssS'media/media-can-play-ogg.html'
+p557
+(dp558
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p559
+ssg6
+g7
+sg159
+g160
+sS'media/video-currentTime-set2.html'
+p560
+(dp561
+g8
+g69
+ssS'media/video-seekable.html'
+p562
+(dp563
+g8
+g69
+ssS'fast/dom/beforeload/video-before-load.html'
+p564
+(dp565
+g8
+g69
+ssS'media/video-played-reset.html'
+p566
+(dp567
+g8
+S"Test of the media element 'played' attribute"
+p568
+ssS'compositing/self-painting-layers2.html'
+p569
+(dp570
+g8
+S'This test should not assert in debug builds.'
+p571
+ssS'media/controls-right-click-on-timebar.html'
+p572
+(dp573
+g8
+S'Test that right clicking on the timebar does not cause a seek.'
+p574
+ssS'media/video-dom-preload.html'
+p575
+(dp576
+g8
+S'consoleWrite("++ Test default attribute value");'
+p577
+ssS'media/video-size.html'
+p578
+(dp579
+g8
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p580
+ssS'media/video-delay-load-event.html'
+p581
+(dp582
+g8
+S"Test the document's load event is delayed until a movie's meta data is available."
+p583
+sg10
+(lp584
+(dp585
+g101
+I01
+sg17
+(lp586
+S'BUGWK64003'
+p587
+asg15
+S' Started around WebKit r90233:r90242'
+p588
+sg76
+I01
+sg49
+I01
+sg322
+I01
+sassS'media/fallback.html'
+p589
+(dp590
+g8
+S'Test that fallback content is not rendered'
+p591
+ssS'fast/layers/video-layer.html'
+p592
+(dp593
+g8
+S'Video element gets layer'
+p594
+ssS'media/controls-strict.html'
+p595
+(dp596
+g8
+S'Drawing the controls in strict mode.'
+p597
+ssS'media/remove-from-document.html'
+p598
+(dp599
+g8
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p600
+ssS'http/tests/media/remove-while-loading.html'
+p601
+(dp602
+g8
+S'Test that removing a media element from the tree while loading does not crash.'
+p603
+ssS'media/video-controls-transformed.html'
+p604
+(dp605
+g8
+S'This test only runs in DRT!'
+p606
+ssS'compositing/video/video-poster.html'
+p607
+(dp608
+g8
+S'Video with poster'
+p609
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p610
+(dp611
+g8
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p612
+ssS'media/video-display-toggle.html'
+p613
+(dp614
+g8
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p615
+ssS'media/video-seek-no-src-exception.html'
+p616
+(dp617
+g8
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p618
+ssS'media/audio-constructor-src.html'
+p619
+(dp620
+g8
+S'Test that Audio("url") constructor loads the specified resource.'
+p621
+ssS'compositing/geometry/clipped-video-controller.html'
+p622
+(dp623
+g8
+S'Clipped Video'
+p624
+ssS'media/video-preload.html'
+p625
+(dp626
+g8
+S"Test to see if media loads automatically when 'preload' is specified."
+p627
+ssS'http/tests/media/video-load-twice.html'
+p628
+(dp629
+g8
+g69
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p630
+(dp631
+g8
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p632
+ssS'media/video-seek-past-end-playing.html'
+p633
+(dp634
+g8
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p635
+ssS'media/video-source.html'
+p636
+(dp637
+g8
+g69
+ssS'http/tests/media/reload-after-dialog.html'
+p638
+(dp639
+g8
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p640
+ssS'media/media-constants.html'
+p641
+(dp642
+g8
+S'Test HTMLMediaElement and MediaError constants.'
+p643
+ssS'media/video-volume.html'
+p644
+(dp645
+g8
+S"Test 'volume' attribute"
+p646
+ssS'media/video-src-source.html'
+p647
+(dp648
+g8
+g69
+ssS'http/tests/appcache/video.html'
+p649
+(dp650
+g8
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p651
+ssg53
+g54
+sg67
+g68
+sS'media/video-canvas-source.html'
+p652
+(dp653
+g8
+S'Drawing to canvas using video with source element does not taint canvas'
+p654
+ssS'media/video-controls-no-scripting.html'
+p655
+(dp656
+g8
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p657
+ssS'media/video-poster-scale.html'
+p658
+(dp659
+g8
+S"'poster' aspect ratio test"
+p660
+ssS'media/video-seek-by-small-increment.html'
+p661
+(dp662
+g8
+S'Test seeking by very small increments.'
+p663
+ssS'media/video-controls-with-mutation-event-handler.html'
+p664
+(dp665
+g8
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p666
+ssS'media/video-zoom-controls.html'
+p667
+(dp668
+g8
+S'Zoomed video with controls.'
+p669
+ssS'media/video-loop.html'
+p670
+(dp671
+g8
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p672
+sg10
+(lp673
+(dp674
+S'WIN'
+p675
+I01
+sg49
+I01
+sg17
+(lp676
+S'BUGCR59415'
+p677
+asg15
+S' BUGCR59415 : cannot repro the flakiness'
+p678
+sg14
+I01
+sg101
+I01
+sassS'http/tests/media/video-play-stall.html'
+p679
+(dp680
+g8
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p681
+sg10
+(lp682
+(dp683
+g101
+I01
+sg17
+(lp684
+S'BUGCR73609'
+p685
+asg15
+S' canplaythrough event is sent too early.'
+p686
+sassS'media/video-seeking.html'
+p687
+(dp688
+g8
+S'Test that seeking attribute is true immediately after a seek,'
+p689
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p690
+(dp691
+g8
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p692
+ssS'media/controls-after-reload.html'
+p693
+(dp694
+g8
+S'Making sure the controller looks ok after a second load().'
+p695
+ssg162
+g163
+sS'media/video-load-networkState.html'
+p696
+(dp697
+g8
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p698
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p699
+(dp700
+g8
+g69
+ssS'compositing/reflections/load-video-in-reflection.html'
+p701
+(dp702
+g8
+S'You should see a reflected video below, rather than the red video background.'
+p703
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p704
+(dp705
+g8
+S'Video overlay'
+p706
+ssS'media/video-controls-rendering.html'
+p707
+(dp708
+g8
+S'Test controls placement.'
+p709
+sg10
+(lp710
+(dp711
+g72
+I01
+sS'LINUX'
+p712
+I01
+sg17
+(lp713
+S'BUGCR74102'
+p714
+asg15
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p715
+sg49
+I01
+sg77
+I01
+sa(dp716
+g44
+I01
+sg72
+I01
+sg17
+(lp717
+S'BUGCR86714'
+p718
+asg15
+g325
+sg76
+I01
+sg77
+I01
+sassS'http/tests/media/video-served-as-text.html'
+p719
+(dp720
+g8
+S"media file served as 'text/plain'"
+p721
+ssS'media/video-pause-empty-events.html'
+p722
+(dp723
+g8
+S'Test that pause() from EMPTY network state triggers load()'
+p724
+ssS'media/video-poster-delayed.html'
+p725
+(dp726
+g8
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p727
+ssS'media/media-load-event.html'
+p728
+(dp729
+g8
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p730
+ssS'http/tests/media/video-error-abort.html'
+p731
+(dp732
+g8
+S"'abort' event test"
+p733
+ssS'media/video-volume-slider.html'
+p734
+(dp735
+g8
+S'Test rendering of volume slider of video tag'
+p736
+ssS'media/video-seek-past-end-paused.html'
+p737
+(dp738
+g8
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p739
+ssS'http/tests/media/video-cookie.html'
+p740
+(dp741
+g8
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p742
+ssS'media/remove-from-document-before-load.html'
+p743
+(dp744
+g8
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p745
+ssg211
+g212
+sS'media/video-duration-known-after-eos.html'
+p746
+(dp747
+g8
+S'Tests that duration is known after playback ended.'
+p748
+ssg214
+g215
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p749
+(dp750
+g8
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p751
+ssS'media/video-timeupdate-during-playback.html'
+p752
+(dp753
+g8
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p754
+ssS'media/video-single-valid-source.html'
+p755
+(dp756
+g8
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p757
+ssS'media/video-src-invalid-remove.html'
+p758
+(dp759
+g8
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p760
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p761
+(dp762
+g8
+S"This test passes if it doesn't alert failure."
+p763
+ssg198
+g199
+sS'media/video-load-readyState.html'
+p764
+(dp765
+g8
+g69
+sssS'nonskip'
+p766
+(dp767
+g404
+g405
+sg350
+g351
+sg679
+g680
+sg247
+g248
+sg536
+g537
+sg670
+g671
+sg707
+g708
+sg581
+g582
+sg368
+g369
+sg317
+g318
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/test_data/more_te_info b/chromium/media/tools/layout_tests/test_data/more_te_info
new file mode 100644
index 00000000000..e020b9e16f5
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_data/more_te_info
@@ -0,0 +1,1891 @@
+(ilayouttest_analyzer_helpers
+AnalyzerResultMap
+p0
+(dp1
+S'result_map'
+p2
+(dp3
+S'skip'
+p4
+(dp5
+S'media/track/track-webvtt-tc004-magicheader.html'
+p6
+(dp7
+S'desc'
+p8
+S'Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.'
+p9
+sS'te_info'
+p10
+(lp11
+(dp12
+S'SKIP'
+p13
+I01
+sS'TIMEOUT'
+p14
+I01
+sS'Comments'
+p15
+S' Tests for WebVTT parser for <track>. Feature is not yet functional.'
+p16
+sS'Bugs'
+p17
+(lp18
+S'BUGWK43668'
+p19
+asassS'media/audio-delete-while-step-button-clicked.html'
+p20
+(dp21
+g8
+S"This tests that events don't continue to target a step button if the media element is deleted while mouse down on button."
+p22
+sg10
+(lp23
+(dp24
+S'FAIL'
+p25
+I01
+sg13
+I01
+sg17
+(lp26
+S'BUGCR25375'
+p27
+aS'BUGCR59399'
+p28
+asg15
+S" Failing because we sometimes emit additional timeupdate events. Test might be WONTFIX because we don't export a step button in the first place."
+p29
+sassS'media/restore-from-page-cache.html'
+p30
+(dp31
+g8
+S"Make sure we don't reload a &lt;video&gt; element when navigating back to an uncached page."
+p32
+sg10
+(lp33
+(dp34
+g13
+I01
+sS'WONTFIX'
+p35
+I01
+sg14
+I01
+sg15
+S' Page Cache - based tests. Chromium disables page cache because the WebKit page cache keeps previously loaded pages alive in memory to be able to quickly substitute them when user clicks History buttons. Chromium wants those to be separate navigations made via browser process to be able to make decision on which renderer process to use for each of them.'
+p36
+sg17
+(lp37
+S'BUGCR19635'
+p38
+asassS'media/context-menu-actions.html'
+p39
+(dp40
+g8
+S'Test the various actions available in the HTML5 media element context-menu.'
+p41
+sg10
+(lp42
+(dp43
+S'CRASH'
+p44
+I01
+sg13
+I01
+sg17
+(lp45
+S'BUGCR59665'
+p46
+aS'BUGWK45021'
+p47
+asg15
+S' BUGCR59415 : cannot repro the flakiness This test needs enhanced eventSender.contextMenu() return value. See https:bugs.webkit.org/show_bug.cgi?id=45021 for more info. UNIMPLEMENTED for chrome'
+p48
+sg14
+I01
+sS'PASS'
+p49
+I01
+sassS'media/track/track-webvtt-tc005-headercomment.html'
+p50
+(dp51
+g8
+S'Tests that the optional comment area under the "WEBVTT" file header is properly ignored. Also, default settings and styling are currently ignored (treated as faulty cues).'
+p52
+sg10
+g11
+ssS'http/tests/media/video-cross-site.html'
+p53
+(dp54
+g8
+S'media file redirects to another site'
+p55
+sg10
+(lp56
+(dp57
+g13
+I01
+sg15
+S' QuickTime reference movies not supported.'
+p58
+sg14
+I01
+sg49
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-data-url.html'
+p59
+(dp60
+g8
+S'Test that audio element can use a data: url'
+p61
+sg10
+(lp62
+(dp63
+g13
+I01
+sg17
+(lp64
+S'BUGCR16779'
+p65
+asg15
+S" These tests are WONTFIX because they use codecs Chromium doesn't support."
+p66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/video-canvas-alpha.html'
+p67
+(dp68
+g8
+S'UNKNOWN'
+p69
+sg10
+(lp70
+(dp71
+g13
+I01
+sS'IMAGE'
+p72
+I01
+sg17
+(lp73
+S'BUGCR74979'
+p74
+asg15
+S" Accelerated 2d for mac isn't supported yet, so SKIP this test for now."
+p75
+sS'MAC'
+p76
+I01
+sS'GPU'
+p77
+I01
+sassS'media/video-can-play-type.html'
+p78
+(dp79
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method.'
+p80
+sg10
+(lp81
+(dp82
+g13
+I01
+sg17
+(lp83
+S'BUGCR16779'
+p84
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-captions.html'
+p85
+(dp86
+g8
+S'Test media element close caption API.'
+p87
+sg10
+(lp88
+(dp89
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit captioning extension. UNIMPLEMENTED"
+p90
+sg17
+(lp91
+S'BUGCR28301'
+p92
+asassS'media/media-can-play-mpeg-audio.html'
+p93
+(dp94
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple mp3 MIME types.'
+p95
+sg10
+(lp96
+(dp97
+g13
+I01
+sg35
+I01
+sg17
+(lp98
+S'BUGCR16779'
+p99
+asg15
+g66
+sS'TEXT'
+p100
+I01
+sassS'media/track/track-webvtt-tc011-blanklines.html'
+p101
+(dp102
+g8
+S'Tests that cues are not affected by multiple newlines \\n, \\r, and \\r\\n and that cue not properly separated are treated as one big cue.'
+p103
+sg10
+g11
+ssS'media/track/track-webvtt-tc012-outoforder.html'
+p104
+(dp105
+g8
+S'Tests cues that are temporally out of order (we allow this).'
+p106
+sg10
+g11
+ssS'media/track/track-webvtt-tc008-timingsnohours.html'
+p107
+(dp108
+g8
+S'Tests cue timings that do not contain hours (they are optional), and tests various syntax errors in timings without hours.'
+p109
+sg10
+g11
+ssS'media/video-size-intrinsic-scale.html'
+p110
+(dp111
+g8
+S'&lt;video&gt; element intrinsic size test'
+p112
+sg10
+(lp113
+(dp114
+g13
+I01
+sg17
+(lp115
+S'BUGCR16779'
+p116
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/audio-mpeg4-supported.html'
+p117
+(dp118
+g8
+S'Test that the audio element supports M4A files.'
+p119
+sg10
+(lp120
+(dp121
+g13
+I01
+sg17
+(lp122
+S'BUGCR16779'
+p123
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/media-fullscreen-not-in-document.html'
+p124
+(dp125
+g8
+S'Test media element fullscreen API when an element is not in the DOM.'
+p126
+sg10
+(lp127
+(dp128
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented the WebKit fullscreen extension. UNIMPLEMENTED"
+p129
+sg17
+(lp130
+S'BUGCR16735'
+p131
+asassS'media/audio-mpeg-supported.html'
+p132
+(dp133
+g8
+S'Test that the audio element supports MPEG files.'
+p134
+sg10
+(lp135
+(dp136
+g13
+I01
+sg17
+(lp137
+S'BUGCR16779'
+p138
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc003-newlines.html'
+p139
+(dp140
+g8
+S'Tests that line terminators \\r, \\n, or \\r\\n are properly parsed, even when there is no newline at eof.'
+p141
+sg10
+g11
+ssS'media/video-document-types.html'
+p142
+(dp143
+g8
+S"This tests that a standalone MPEG-4 file with 'sdsm' and 'odsm' tracks is opened in a MediaDocument."
+p144
+sg10
+(lp145
+(dp146
+g13
+I01
+sg17
+(lp147
+S'BUGCR16779'
+p148
+asg15
+g66
+sg14
+I01
+sg25
+I01
+sg35
+I01
+sassS'media/track/track-webvtt-tc002-bom.html'
+p149
+(dp150
+g8
+S'Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.'
+p151
+sg10
+g11
+ssS'media/video-does-not-loop.html'
+p152
+(dp153
+g8
+S"Test to make sure QuickTime movie saved with 'loop' user data does not loop automatically."
+p154
+sg10
+(lp155
+(dp156
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+S" Doesn't apply to Chromium (QuickTime-specific behavior)"
+p157
+sassS'media/track/track-webvtt-tc000-empty.html'
+p158
+(dp159
+g8
+S'Tests that an empty file is not recognized as a WebVTT file.'
+p160
+sg10
+g11
+ssS'media/media-can-play-mpeg4-video.html'
+p161
+(dp162
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with'
+p163
+sg10
+(lp164
+(dp165
+g13
+I01
+sg35
+I01
+sg17
+(lp166
+S'BUGWK45102'
+p167
+asg15
+g66
+sg100
+I01
+sassS'compositing/video/video-background-color.html'
+p168
+(dp169
+g8
+S'Video with background color'
+p170
+sg10
+(lp171
+(dp172
+g25
+I01
+sg13
+I01
+sg35
+I01
+sg17
+(lp173
+S'BUGWK55519'
+p174
+asg15
+S" Chromium's video codecs don't support alpha information encoded in the video data, so this test is not applicable."
+p175
+sassS'media/track/track-webvtt-tc010-notimings.html'
+p176
+(dp177
+g8
+S'Tests cue without timings are ignored.'
+p178
+sg10
+g11
+ssS'media/video-timeupdate-reverse-play.html'
+p179
+(dp180
+g8
+S"Tests that a 'timeupdate' event is fired when a movie plays<br> in reverse to time zero."
+p181
+sg10
+(lp182
+(dp183
+g13
+I01
+sg14
+I01
+sg15
+S" We haven't implemented reverse audio/video playback. UNIMPLEMENTED BUGCR33099 Implement reverse audio/video playback"
+p184
+sg17
+(lp185
+S'BUGCR33099'
+p186
+asassS'http/tests/media/video-buffered.html'
+p187
+(dp188
+g8
+g69
+sg10
+(lp189
+(dp190
+g13
+I01
+sg17
+(lp191
+S'BUGCR49165'
+p192
+asg15
+S' video.buffered multiple TimeRanges support.'
+p193
+sg49
+I01
+sassS'media/track/track-webvtt-tc001-utf8.html'
+p194
+(dp195
+g8
+S'Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as WebVTT a file (we do allow it, it just looks ugly).'
+p196
+sg10
+g11
+ssS'media/track/track-webvtt-tc013-settings.html'
+p197
+(dp198
+g8
+S'Tests WebVTT settings.'
+p199
+sg10
+g11
+ssS'media/media-fullscreen-inline.html'
+p200
+(dp201
+g8
+S'Test media element fullscreen API when an element is in the DOM.'
+p202
+sg10
+(lp203
+(dp204
+g13
+I01
+sg14
+I01
+sg15
+g129
+sg17
+(lp205
+S'BUGCR16735'
+p206
+asassS'media/track/track-webvtt-tc007-cuenoid.html'
+p207
+(dp208
+g8
+S'Tests empty cue identifiers (they are optional), but makes sure "-->" found leads to discarded cue.'
+p209
+sg10
+g11
+ssS'media/track/track-webvtt-tc009-timingshour.html'
+p210
+(dp211
+g8
+S'Tests cue timings that contain hours (they are optional), and tests various syntax errors in timings with hours.'
+p212
+sg10
+g11
+ssS'media/track/track-webvtt-tc006-cueidentifiers.html'
+p213
+(dp214
+g8
+S'Tests that any text other than "-->" is recognized as optional cue identifier.'
+p215
+sg10
+g11
+ssS'media/video-element-other-namespace-crash.html'
+p216
+(dp217
+g8
+g69
+sg10
+(lp218
+(dp219
+g13
+I01
+sg35
+I01
+sg14
+I01
+sg15
+g66
+sg17
+(lp220
+S'BUGCR68289'
+p221
+asassS'media/video-reverse-play-duration.html'
+p222
+(dp223
+g8
+S'Tests that duration is not set to zero when playing in reverse to the origin.'
+p224
+sg10
+(lp225
+(dp226
+g13
+I01
+sg14
+I01
+sg15
+g184
+sg17
+(lp227
+S'BUGCR33099'
+p228
+asasssS'whole'
+p229
+(dp230
+S'media/video-source-type.html'
+p231
+(dp232
+g8
+S'&lt;source&gt; @type attribute'
+p233
+ssS'media/media-startTime.html'
+p234
+(dp235
+g8
+S"Test the, so far unused, 'startTime' attribute."
+p236
+ssS'media/video-src-set.html'
+p237
+(dp238
+g8
+S'Test that setting src attribute triggers load'
+p239
+ssg20
+g21
+sS'media/video-played-ranges-1.html'
+p240
+(dp241
+g8
+S"Test of the media element 'played' attribute, ranges part 1."
+p242
+ssS'media/video-layer-crash.html'
+p243
+(dp244
+g8
+S'Test dynamic removal of transformed and reflected video'
+p245
+ssS'http/tests/media/video-play-stall-seek.html'
+p246
+(dp247
+g8
+S'Test that playback can be resumed by seeking backwards after load stalls.'
+p248
+sg10
+(lp249
+(dp250
+g14
+I01
+sg15
+S' Timing out.'
+p251
+sg17
+(lp252
+S'BUGCR78376'
+p253
+asassg59
+g60
+sg78
+g79
+sg85
+g86
+sS'http/tests/media/video-referer.html'
+p254
+(dp255
+g8
+S'Tests that the media player will send the relevant referer when requesting the media file.<br/>'
+p256
+ssS'media/video-source-removed.html'
+p257
+(dp258
+g8
+S'consoleWrite("PASS: A crash did not occur when removing &lt;source&gt; elements.<br>");'
+p259
+ssS'media/unsupported-tracks.html'
+p260
+(dp261
+g8
+S'Test that QuickTime file with unsupported track types only generates an error.'
+p262
+ssg117
+g118
+sS'media/audio-no-installed-engines.html'
+p263
+(dp264
+g8
+S'PASSED -- crash using Audio with no installed engines bug 27479.'
+p265
+ssg124
+g125
+sS'media/video-dom-src.html'
+p266
+(dp267
+g8
+g69
+ssS'media/media-blocked-by-willsendrequest.html'
+p268
+(dp269
+g8
+S'consoleWrite("This test can only be run in DumpRenderTree!<br><br>");'
+p270
+ssS'media/video-error-does-not-exist.html'
+p271
+(dp272
+g8
+S'Test that the media element is in correct state after load fails.'
+p273
+ssS'media/video-play-pause-events.html'
+p274
+(dp275
+g8
+S'Test that calling play() and pause() triggers async play, timeupdate and pause events.'
+p276
+ssS'media/video-display-none-crash.html'
+p277
+(dp278
+g8
+S'Test that pause() after changing display to "none" doesn\'t cause a crash.'
+p279
+ssS'media/video-src-plus-source.html'
+p280
+(dp281
+g8
+S"Test that a &lt;source&gt; element is not used when a bogus 'src' attribute is present"
+p282
+ssS'media/video-source-none-supported.html'
+p283
+(dp284
+g8
+S'no usable &lt;source&gt; test'
+p285
+ssS'media/video-poster-blocked-by-willsendrequest.html'
+p286
+(dp287
+g8
+S'consoleWrite("<b>This test can only be run in DumpRenderTree!</b>");'
+p288
+ssg152
+g153
+sS'media/video-src.html'
+p289
+(dp290
+g8
+g69
+ssS'media/audio-controls-rendering.html'
+p291
+(dp292
+g8
+S'Test controls placement.'
+p293
+ssg168
+g169
+sS'media/video-source-inserted.html'
+p294
+(dp295
+g8
+S'networkState after inserting &lt;source&gt; test'
+p296
+ssS'media/media-can-play-octet-stream.html'
+p297
+(dp298
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with "application/octet-stream".'
+p299
+ssS'media/constructors.html'
+p300
+(dp301
+g8
+S'Test that media constructors behave consistently.'
+p302
+ssS'media/video-source-media.html'
+p303
+(dp304
+g8
+g69
+ssg187
+g188
+sS'http/tests/security/local-video-source-from-remote.html'
+p305
+(dp306
+g8
+S'This test only behaves correctly in DRT'
+p307
+ssg194
+g195
+sS'media/video-source-type-params.html'
+p308
+(dp309
+g8
+g69
+ssS'fast/canvas/webgl/context-lost.html'
+p310
+(dp311
+g8
+S'debug("Test valid context");'
+p312
+ssS'media/media-can-play-wav-audio.html'
+p313
+(dp314
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method with multiple .wav MIME types.'
+p315
+ssS'media/video-source-error.html'
+p316
+(dp317
+g8
+S'&lt;video&gt; and &lt;source&gt; error test'
+p318
+sg10
+(lp319
+(dp320
+S'DEBUG'
+p321
+I01
+sg100
+I01
+sg17
+(lp322
+S'BUGWK66310'
+p323
+asg15
+S''
+p324
+sg49
+I01
+sassS'media/video-no-audio.html'
+p325
+(dp326
+g8
+S'Movie with no audio track. The volume button should not render.'
+p327
+ssS'media/svg-as-image-with-media-blocked.html'
+p328
+(dp329
+g8
+S'This test attempts to load foreignObject audio and video embedded in an SVG'
+p330
+ssg207
+g208
+sg107
+g108
+sS'media/video-click-dblckick-standalone.html'
+p331
+(dp332
+g8
+S'This tests that clicking on a standalone video will pause and double-clicking will play.'
+p333
+ssS'media/video-pause-immediately.html'
+p334
+(dp335
+g8
+S'Test that pausing the media element has an immediate effect on the clock.'
+p336
+ssS'fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html'
+p337
+(dp338
+g8
+g69
+ssg222
+g223
+sS'http/tests/security/local-video-src-from-remote.html'
+p339
+(dp340
+g8
+S'This test only works in DRT'
+p341
+ssg200
+g201
+sS'media/video-controls-in-media-document.html'
+p342
+(dp343
+g8
+g69
+ssS'media/remove-from-document-no-load.html'
+p344
+(dp345
+g8
+S'Test that removing a media element from the tree when no media has been loaded does not generate a loadstart event.'
+p346
+ssS'media/video-currentTime.html'
+p347
+(dp348
+g8
+g69
+ssS'media/video-frame-accurate-seek.html'
+p349
+(dp350
+g8
+S'Test that setting currentTime is frame-accurate. The three videos below should be showing frames 12, 13, and 14.'
+p351
+sg10
+(lp352
+(dp353
+g72
+I01
+sg17
+(lp354
+S'BUGCR72223'
+p355
+asg15
+g324
+sg49
+I01
+sassg30
+g31
+sg39
+g40
+sS'media/media-controls-clone-crash.html'
+p356
+(dp357
+g8
+S'Test passes if it does not crash.'
+p358
+ssg50
+g51
+sS'media/controls-css-overload.html'
+p359
+(dp360
+g8
+S"Testing that overloading some controls doesn't crash the browser"
+p361
+ssS'media/video-display-aspect-ratio.html'
+p362
+(dp363
+g8
+g69
+ssS'media/video-currentTime-set.html'
+p364
+(dp365
+g8
+S"Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time"
+p366
+ssS'media/media-blocked-by-beforeload.html'
+p367
+(dp368
+g8
+S'Test to ensure that a media file blocked by a beforeload handler generates an error'
+p369
+sg10
+(lp370
+(dp371
+g100
+I01
+sg17
+(lp372
+S'BUGWK66310'
+p373
+asg15
+g324
+sg49
+I01
+sassg104
+g105
+sS'media/video-controls-visible-audio-only.html'
+p374
+(dp375
+g8
+S'This test only runs in DRT!'
+p376
+ssS'http/tests/media/video-play-progress.html'
+p377
+(dp378
+g8
+S'Test that at least one progress event is fired after starting to load the video.'
+p379
+ssg110
+g111
+sS'media/video-source-moved.html'
+p380
+(dp381
+g8
+S'moving &lt;source&gt; element test'
+p382
+ssg101
+g102
+sS'media/video-src-none.html'
+p383
+(dp384
+g8
+g69
+ssS'media/video-controls-zoomed.html'
+p385
+(dp386
+g8
+S'This test only runs in DRT!'
+p387
+ssS'media/video-controls.html'
+p388
+(dp389
+g8
+S"Test 'controls' attribute"
+p390
+ssS'media/controls-without-preload.html'
+p391
+(dp392
+g8
+S'The controls should not depend on preload value.'
+p393
+ssS'media/video-played-collapse.html'
+p394
+(dp395
+g8
+S"Test of the media element 'played' attribute"
+p396
+ssS'compositing/self-painting-layers.html'
+p397
+(dp398
+g8
+S'Self painting layers'
+p399
+ssS'media/audio-controls-do-not-fade-out.html'
+p400
+(dp401
+g8
+S'This tests that audio controls do not fade out when the audio is playing.'
+p402
+ssS'media/media-document-audio-repaint.html'
+p403
+(dp404
+g8
+S'This tests that in a standalone media document with audio content, the media element repaints correctly'
+p405
+sg10
+(lp406
+(dp407
+g100
+I01
+sg72
+I01
+sg17
+(lp408
+S'BUGCR75354'
+p409
+aS'BUGWK55718'
+p410
+asg15
+S' This test needs completely new baselines.'
+p411
+sS'IMAGE+TEXT'
+p412
+I01
+sa(dp413
+S'NEWADDED'
+p414
+I01
+sg100
+I01
+sg72
+I01
+sg17
+g408
+sg15
+g411
+sg412
+I01
+sassS'compositing/geometry/video-opacity-overlay.html'
+p415
+(dp416
+g8
+S'Video overlay'
+p417
+ssS'media/video-source-error-no-candidate.html'
+p418
+(dp419
+g8
+S"Test that 'error' events are fired from &lt;source&gt; element when it can not be used."
+p420
+ssS'media/audio-constructor.html'
+p421
+(dp422
+g8
+S'Test that Audio() object loads the resource after src attribute is set and load() is called.'
+p423
+ssS'media/controls-styling.html'
+p424
+(dp425
+g8
+S'The look of the controls should not change.'
+p426
+ssS'media/video-buffered.html'
+p427
+(dp428
+g8
+g69
+ssS'media/event-attributes.html'
+p429
+(dp430
+g8
+g69
+ssg176
+g177
+sg179
+g180
+sS'http/tests/media/text-served-as-text.html'
+p431
+(dp432
+g8
+S"text file served as 'text/plain'"
+p433
+ssS'http/tests/media/video-cancel-load.html'
+p434
+(dp435
+g8
+S'Cancel loading a video file and access its properties afterwards.'
+p436
+ssS'media/unsupported-rtsp.html'
+p437
+(dp438
+g8
+S'Test that QuickTime file with RTSP URL generates a load error.'
+p439
+ssS'media/media-controls-clone.html'
+p440
+(dp441
+g8
+S'<video controls id=v></video><audio controls id=a></audio>'
+p442
+ssS'media/broken-video.html'
+p443
+(dp444
+g8
+S'Test that QuickTime file with broken content generates an error.'
+p445
+ssS'media/video-plays-past-end-of-test.html'
+p446
+(dp447
+g8
+g69
+ssS'http/tests/canvas/webgl/origin-clean-conformance.html'
+p448
+(dp449
+g8
+S'WebGL Origin Restrictions Conformance Tests'
+p450
+ssS'media/video-replaces-poster.html'
+p451
+(dp452
+g8
+S'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>'
+p453
+ssS'media/video-autoplay.html'
+p454
+(dp455
+g8
+g69
+ssS'media/video-set-rate-from-pause.html'
+p456
+(dp457
+g8
+S'Test that setting a non-zero rate causes an async timeupdate event.'
+p458
+ssS'media/video-src-remove.html'
+p459
+(dp460
+g8
+S"Test that removing valid 'src' attribute DOES NOT trigger load of &lt;source&gt; elements"
+p461
+ssS'media/csp-blocks-video.html'
+p462
+(dp463
+g8
+S"This test passes if it doesn't alert failure."
+p464
+ssS'media/controls-drag-timebar.html'
+p465
+(dp466
+g8
+S'Test that dragging the timebar thumb causes seeks.'
+p467
+ssS'media/audio-constructor-preload.html'
+p468
+(dp469
+g8
+S"Test that Audio() sets 'preload' attribute."
+p470
+ssS'media/video-src-invalid-poster.html'
+p471
+(dp472
+g8
+g69
+ssS'media/adopt-node-crash.html'
+p473
+(dp474
+g8
+S"Tests that we don't crash when moving a video element to a new document."
+p475
+ssS'media/video-playbackrate.html'
+p476
+(dp477
+g8
+S'test playbackRate and defaultPlaybackRate'
+p478
+ssS'media/video-muted.html'
+p479
+(dp480
+g8
+S"Test 'muted' attribute"
+p481
+ssS'media/video-src-change.html'
+p482
+(dp483
+g8
+S'1. Test that an invalid src attribute fires an error when the file fails to load.<br>'
+p484
+ssg216
+g217
+sS'media/video-play-pause-exception.html'
+p485
+(dp486
+g8
+S'Video has no src. Test that the playing event is not dispatched.'
+p487
+ssS'fast/dom/shadow/frameless-media-element-crash.html'
+p488
+(dp489
+g8
+g69
+ssS'media/audio-play-event.html'
+p490
+(dp491
+g8
+S"Test that a 'play' event listener is triggered when fired by a new audio element."
+p492
+ssS'media/before-load-member-access.html'
+p493
+(dp494
+g8
+S'Test that accessing member of a non loaded video works.'
+p495
+ssS'media/video-width-height.html'
+p496
+(dp497
+g8
+g69
+ssS'media/audio-repaint.html'
+p498
+(dp499
+g8
+S'This tests that in a html document with inline audio content, the media element repaints correctly'
+p500
+ssS'media/video-currentTime-delay.html'
+p501
+(dp502
+g8
+S'Test a delay in playing the movie results in a canPlay event.'
+p503
+ssS'media/video-aspect-ratio.html'
+p504
+(dp505
+g8
+S'Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size.'
+p506
+ssS'media/video-transformed.html'
+p507
+(dp508
+g8
+S'Test painting of transformed video'
+p509
+ssS'fast/dom/beforeload/remove-video-in-beforeload-listener.html'
+p510
+(dp511
+g8
+S'This page tests that you can correctly remove a video object in a beforeload listener without causing a crash.'
+p512
+ssS'media/invalid-media-url-crash.html'
+p513
+(dp514
+g8
+S'Tests that invalid media src url does not result in crash.'
+p515
+ssS'media/video-empty-source.html'
+p516
+(dp517
+g8
+S'Slider drawing with no source. The controls should render correctly.'
+p518
+ssg93
+g94
+sS'media/video-poster.html'
+p519
+(dp520
+g8
+S'Test &lt;video&gt; element with and without a poster.'
+p521
+ssS'media/media-document-audio-size.html'
+p522
+(dp523
+g8
+S'This tests that in a standalone media document with audio content, the media element has non-zero'
+p524
+ssg132
+g133
+sS'compositing/overflow/overflow-compositing-descendant.html'
+p525
+(dp526
+g8
+S'You should see a green box under the video. If you see red, the test failed.'
+p527
+ssS'media/video-dom-autoplay.html'
+p528
+(dp529
+g8
+g69
+ssS'media/media-ended.html'
+p530
+(dp531
+g8
+S'<b>Test ended by:</b>'
+p532
+ssS'media/video-no-autoplay.html'
+p533
+(dp534
+g8
+S'Test that play event does not fire when "src" set with no autoplay attribute.'
+p535
+ssS'media/video-zoom.html'
+p536
+(dp537
+g8
+S'150% zoom, with width and height attributes'
+p538
+sg10
+(lp539
+(dp540
+g44
+I01
+sg72
+I01
+sg17
+(lp541
+S'BUGCR86714'
+p542
+asg15
+g324
+sg76
+I01
+sg77
+I01
+sassS'media/video-append-source.html'
+p543
+(dp544
+g8
+g69
+ssg139
+g140
+sS'http/tests/media/pdf-served-as-pdf.html'
+p545
+(dp546
+g8
+S"PDF file served as 'application/pdf'"
+p547
+ssS'media/video-play-empty-events.html'
+p548
+(dp549
+g8
+S'Test that play() from EMPTY network state triggers load() and async play event.'
+p550
+ssg149
+g150
+sS'media/audio-only-video-intrinsic-size.html'
+p551
+(dp552
+g8
+S'This tests the intrinsic size of a video element is the default 300&#xd7;150 before metadata is'
+p553
+ssg142
+g143
+sS'media/audio-delete-while-slider-thumb-clicked.html'
+p554
+(dp555
+g8
+S"This tests that events don't continue to target a slider thumb if the media element is deleted while scrubbing."
+p556
+ssS'media/media-can-play-ogg.html'
+p557
+(dp558
+g8
+S'Test HTMLMediaElement <em>canPlayType()</em> method for ogg media containers.'
+p559
+ssg6
+g7
+sg158
+g159
+sS'media/video-currentTime-set2.html'
+p560
+(dp561
+g8
+g69
+ssS'media/video-seekable.html'
+p562
+(dp563
+g8
+g69
+ssS'fast/dom/beforeload/video-before-load.html'
+p564
+(dp565
+g8
+g69
+ssS'media/video-played-reset.html'
+p566
+(dp567
+g8
+S"Test of the media element 'played' attribute"
+p568
+ssS'compositing/self-painting-layers2.html'
+p569
+(dp570
+g8
+S'This test should not assert in debug builds.'
+p571
+ssS'media/controls-right-click-on-timebar.html'
+p572
+(dp573
+g8
+S'Test that right clicking on the timebar does not cause a seek.'
+p574
+ssS'media/video-dom-preload.html'
+p575
+(dp576
+g8
+S'consoleWrite("++ Test default attribute value");'
+p577
+ssS'media/video-size.html'
+p578
+(dp579
+g8
+S"Test &lt;video&gt; element size with and without 'src' and 'poster' attributes."
+p580
+ssS'media/video-delay-load-event.html'
+p581
+(dp582
+g8
+S"Test the document's load event is delayed until a movie's meta data is available."
+p583
+sg10
+(lp584
+(dp585
+g100
+I01
+sg17
+(lp586
+S'BUGWK64003'
+p587
+asg15
+S' Started around WebKit r90233:r90242'
+p588
+sg76
+I01
+sg49
+I01
+sg321
+I01
+sassS'media/fallback.html'
+p589
+(dp590
+g8
+S'Test that fallback content is not rendered'
+p591
+ssS'fast/layers/video-layer.html'
+p592
+(dp593
+g8
+S'Video element gets layer'
+p594
+ssS'media/controls-strict.html'
+p595
+(dp596
+g8
+S'Drawing the controls in strict mode.'
+p597
+ssS'media/remove-from-document.html'
+p598
+(dp599
+g8
+S'Test that removing a media element from the tree pauses playback but does not unload the media.'
+p600
+ssS'http/tests/media/remove-while-loading.html'
+p601
+(dp602
+g8
+S'Test that removing a media element from the tree while loading does not crash.'
+p603
+ssS'media/video-controls-transformed.html'
+p604
+(dp605
+g8
+S'This test only runs in DRT!'
+p606
+ssS'compositing/video/video-poster.html'
+p607
+(dp608
+g8
+S'Video with poster'
+p609
+ssS'http/tests/media/media-can-load-when-hidden.html'
+p610
+(dp611
+g8
+S'Test HTMLMediaElement to be sure that the video is getting loaded even if the element'
+p612
+ssS'media/video-display-toggle.html'
+p613
+(dp614
+g8
+S"This tests that toggling the display property won't make the controls disappear.<br>"
+p615
+ssS'media/video-seek-no-src-exception.html'
+p616
+(dp617
+g8
+S"Test that seeking video with no 'src' attribute throws an INVALID_STATE_ERR exception."
+p618
+ssS'media/audio-constructor-src.html'
+p619
+(dp620
+g8
+S'Test that Audio("url") constructor loads the specified resource.'
+p621
+ssS'compositing/geometry/clipped-video-controller.html'
+p622
+(dp623
+g8
+S'Clipped Video'
+p624
+ssS'media/video-preload.html'
+p625
+(dp626
+g8
+S"Test to see if media loads automatically when 'preload' is specified."
+p627
+ssS'http/tests/media/video-load-twice.html'
+p628
+(dp629
+g8
+g69
+ssS'http/tests/security/local-video-poster-from-remote.html'
+p630
+(dp631
+g8
+S'This test requires the run-webkit httpd server (run-webkit-httpd)'
+p632
+ssS'media/video-seek-past-end-playing.html'
+p633
+(dp634
+g8
+S"Test that seeking video with 'loop' past it's end rewinds to the beginning and continues playback."
+p635
+ssS'media/video-source.html'
+p636
+(dp637
+g8
+g69
+ssS'http/tests/media/reload-after-dialog.html'
+p638
+(dp639
+g8
+S"Test this by loading a movie slowly and showing a dialog when a 'loadstart' event <br>"
+p640
+ssS'media/media-constants.html'
+p641
+(dp642
+g8
+S'Test HTMLMediaElement and MediaError constants.'
+p643
+ssS'media/video-volume.html'
+p644
+(dp645
+g8
+S"Test 'volume' attribute"
+p646
+ssS'media/video-src-source.html'
+p647
+(dp648
+g8
+g69
+ssS'http/tests/appcache/video.html'
+p649
+(dp650
+g8
+S'Test that &lt;video&gt; can be loaded from the application cache.'
+p651
+ssg53
+g54
+sg67
+g68
+sS'media/video-canvas-source.html'
+p652
+(dp653
+g8
+S'Drawing to canvas using video with source element does not taint canvas'
+p654
+ssS'media/video-controls-no-scripting.html'
+p655
+(dp656
+g8
+S'Tests that the built-in controls are always enabled when JavaScript is disabled.'
+p657
+ssS'media/video-poster-scale.html'
+p658
+(dp659
+g8
+S"'poster' aspect ratio test"
+p660
+ssS'media/video-seek-by-small-increment.html'
+p661
+(dp662
+g8
+S'Test seeking by very small increments.'
+p663
+ssS'media/video-controls-with-mutation-event-handler.html'
+p664
+(dp665
+g8
+S"This tests that we don't crash while creating a video element while a DOMSubtreeModified even handler is registered."
+p666
+ssS'media/video-zoom-controls.html'
+p667
+(dp668
+g8
+S'Zoomed video with controls.'
+p669
+ssS'media/video-loop.html'
+p670
+(dp671
+g8
+S'consoleWrite("<em>++ Test setting/removing the attribute.</em>");'
+p672
+sg10
+(lp673
+(dp674
+S'WIN'
+p675
+I01
+sg49
+I01
+sg17
+(lp676
+S'BUGCR59415'
+p677
+asg15
+S' BUGCR59415 : cannot repro the flakiness'
+p678
+sg14
+I01
+sg100
+I01
+sassS'http/tests/media/video-play-stall.html'
+p679
+(dp680
+g8
+S'Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.'
+p681
+sg10
+(lp682
+(dp683
+g100
+I01
+sg17
+(lp684
+S'BUGCR73609'
+p685
+asg15
+S' canplaythrough event is sent too early.'
+p686
+sassS'media/video-seeking.html'
+p687
+(dp688
+g8
+S'Test that seeking attribute is true immediately after a seek,'
+p689
+ssS'compositing/overflow/scroll-ancestor-update.html'
+p690
+(dp691
+g8
+S'The green box should obscure the red box, and move when you drag the scrollbar.'
+p692
+ssS'media/controls-after-reload.html'
+p693
+(dp694
+g8
+S'Making sure the controller looks ok after a second load().'
+p695
+ssg161
+g162
+sS'media/video-load-networkState.html'
+p696
+(dp697
+g8
+S'Test that setting src to an invalid url triggers load(), which sets networkState'
+p698
+ssS'http/tests/security/contentSecurityPolicy/media-src-allowed.html'
+p699
+(dp700
+g8
+g69
+ssS'compositing/reflections/load-video-in-reflection.html'
+p701
+(dp702
+g8
+S'You should see a reflected video below, rather than the red video background.'
+p703
+ssS'compositing/geometry/video-fixed-scrolling.html'
+p704
+(dp705
+g8
+S'Video overlay'
+p706
+ssS'media/video-controls-rendering.html'
+p707
+(dp708
+g8
+S'Test controls placement.'
+p709
+sg10
+(lp710
+(dp711
+g72
+I01
+sS'LINUX'
+p712
+I01
+sg17
+(lp713
+S'BUGCR74102'
+p714
+asg15
+S" 2 pixel stretching when rendering some videos with the GPU (Now it's flaky)"
+p715
+sg49
+I01
+sg77
+I01
+sa(dp716
+g44
+I01
+sg72
+I01
+sg17
+(lp717
+S'BUGCR86714'
+p718
+asg15
+g324
+sg76
+I01
+sg77
+I01
+sassS'http/tests/media/video-served-as-text.html'
+p719
+(dp720
+g8
+S"media file served as 'text/plain'"
+p721
+ssS'media/video-pause-empty-events.html'
+p722
+(dp723
+g8
+S'Test that pause() from EMPTY network state triggers load()'
+p724
+ssS'media/video-poster-delayed.html'
+p725
+(dp726
+g8
+S'Delayed load of poster should not overwrite intrinsic size of video'
+p727
+ssS'media/media-load-event.html'
+p728
+(dp729
+g8
+S'Test that media file is not reloaded when an element is inserted into the DOM.'
+p730
+ssS'http/tests/media/video-error-abort.html'
+p731
+(dp732
+g8
+S"'abort' event test"
+p733
+ssS'media/video-volume-slider.html'
+p734
+(dp735
+g8
+S'Test rendering of volume slider of video tag'
+p736
+ssS'media/video-seek-past-end-paused.html'
+p737
+(dp738
+g8
+S"Test that seeking paused video past it's duration time sets currentTime to duration and leaves video paused."
+p739
+ssS'http/tests/media/video-cookie.html'
+p740
+(dp741
+g8
+S'Tests that the media player will send the relevant cookies when requesting the media file.<br/>'
+p742
+ssS'media/remove-from-document-before-load.html'
+p743
+(dp744
+g8
+S'<body onload="document.body.innerHTML=\'PASS: A crash did not occur when the media element was removed before loading.\';'
+p745
+ssg210
+g211
+sS'media/video-duration-known-after-eos.html'
+p746
+(dp747
+g8
+S'Tests that duration is known after playback ended.'
+p748
+ssg213
+g214
+sS'http/tests/media/video-play-stall-before-meta-data.html'
+p749
+(dp750
+g8
+S'Test that stalling very early, while loading meta-data, stops delaying the load event.'
+p751
+ssS'media/video-timeupdate-during-playback.html'
+p752
+(dp753
+g8
+S"Test 'timeupdate' events are posted while playing but not while paused."
+p754
+ssS'media/video-single-valid-source.html'
+p755
+(dp756
+g8
+S'Test that a single valid &lt;source&gt; element loads correctly'
+p757
+ssS'media/video-src-invalid-remove.html'
+p758
+(dp759
+g8
+S"Test that removing 'src' attribute does NOT trigger load of &lt;source&gt; elements"
+p760
+ssS'http/tests/security/contentSecurityPolicy/media-src-blocked.html'
+p761
+(dp762
+g8
+S"This test passes if it doesn't alert failure."
+p763
+ssg197
+g198
+sS'media/video-load-readyState.html'
+p764
+(dp765
+g8
+g69
+sssS'nonskip'
+p766
+(dp767
+g403
+g404
+sg349
+g350
+sg679
+g680
+sg246
+g247
+sg536
+g537
+sg670
+g671
+sg707
+g708
+sg581
+g582
+sg367
+g368
+sg316
+g317
+sssb. \ No newline at end of file
diff --git a/chromium/media/tools/layout_tests/test_expectations.py b/chromium/media/tools/layout_tests/test_expectations.py
new file mode 100644
index 00000000000..58b21de6883
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_expectations.py
@@ -0,0 +1,123 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A module to analyze test expectations for Webkit layout tests."""
+
+import urllib2
+
+from webkitpy.layout_tests.models.test_expectations import *
+
+# Default location for chromium test expectation file.
+# TODO(imasaki): support multiple test expectations files.
+DEFAULT_TEST_EXPECTATIONS_LOCATION = (
+ 'http://src.chromium.org/blink/trunk/LayoutTests/TestExpectations')
+
+# The following is from test expectation syntax. The detail can be found in
+# http://www.chromium.org/developers/testing/webkit-layout-tests#TOC-Test-Expectations
+# <decision> ::== [SKIP] [WONTFIX] [SLOW]
+DECISION_NAMES = ['SKIP', 'WONTFIX', 'SLOW']
+# <config> ::== RELEASE | DEBUG
+CONFIG_NAMES = ['RELEASE', 'DEBUG']
+# Only hard code keywords we don't expect to change. Determine the rest from
+# the format of the status line.
+KNOWN_TE_KEYWORDS = DECISION_NAMES + CONFIG_NAMES
+
+
+class TestExpectations(object):
+ """A class to model the content of test expectation file for analysis.
+
+ This class retrieves the TestExpectations file via HTTP from WebKit and uses
+ the WebKit layout test processor to process each line.
+
+ The resulting dictionary is stored in |all_test_expectation_info| and looks
+ like:
+
+ {'<test name>': [{'<modifier0>': True, '<modifier1>': True, ...,
+ 'Platforms: ['<platform0>', ... ], 'Bugs': ['....']}]}
+
+ Duplicate keys are merged (though technically they shouldn't exist).
+
+ Example:
+ crbug.com/145590 [ Android ] \
+ platform/chromium/media/video-frame-size-change.html [ Timeout ]
+ webkit.org/b/84724 [ SnowLeopard ] \
+ platform/chromium/media/video-frame-size-change.html \
+ [ ImageOnlyFailure Pass ]
+
+ {'platform/chromium/media/video-frame-size-change.html': [{'IMAGE': True,
+ 'Bugs': ['BUGWK84724', 'BUGCR145590'], 'Comments': '',
+ 'Platforms': ['SNOWLEOPARD', 'ANDROID'], 'TIMEOUT': True, 'PASS': True}]}
+ """
+
+ def __init__(self, url=DEFAULT_TEST_EXPECTATIONS_LOCATION):
+ """Read the test expectation file from the specified URL and parse it.
+
+ Args:
+ url: A URL string for the test expectation file.
+
+ Raises:
+ NameError when the test expectation file cannot be retrieved from |url|.
+ """
+ self.all_test_expectation_info = {}
+ resp = urllib2.urlopen(url)
+ if resp.code != 200:
+ raise NameError('Test expectation file does not exist in %s' % url)
+ # Start parsing each line.
+ for line in resp.read().split('\n'):
+ line = line.strip()
+ # Skip comments.
+ if line.startswith('#'):
+ continue
+ testname, te_info = self.ParseLine(line)
+ if not testname or not te_info:
+ continue
+ if testname in self.all_test_expectation_info:
+ # Merge keys if entry already exists.
+ for k in te_info.keys():
+ if (isinstance(te_info[k], list) and
+ k in self.all_test_expectation_info[testname]):
+ self.all_test_expectation_info[testname][0][k] += te_info[k]
+ else:
+ self.all_test_expectation_info[testname][0][k] = te_info[k]
+ else:
+ self.all_test_expectation_info[testname] = [te_info]
+
+ @staticmethod
+ def ParseLine(line):
+ """Parses the provided line using WebKit's TextExpecations parser.
+
+ Returns:
+ Tuple of test name, test expectations dictionary. See class documentation
+ for the format of the dictionary
+ """
+ test_expectation_info = {}
+ parsed = TestExpectationParser._tokenize_line('TestExpectations', line, 0)
+ if parsed.is_invalid():
+ return None, None
+
+ test_expectation_info['Comments'] = parsed.comment or ''
+
+ # Split the modifiers dictionary into the format we want.
+ remaining_modifiers = list(parsed.modifiers)
+ test_expectation_info['Bugs'] = []
+ for m in parsed.modifiers:
+ if (m.startswith(WEBKIT_BUG_PREFIX) or
+ m.startswith(CHROMIUM_BUG_PREFIX) or
+ m.startswith(V8_BUG_PREFIX) or
+ m.startswith(NAMED_BUG_PREFIX)):
+ test_expectation_info['Bugs'].append(m)
+ remaining_modifiers.remove(m)
+ elif m in KNOWN_TE_KEYWORDS:
+ test_expectation_info[m] = True
+ remaining_modifiers.remove(m)
+
+ # The modifiers left over should all be platform names.
+ test_expectation_info['Platforms'] = list(remaining_modifiers)
+
+ # Shovel the expectations and modifiers in as "<key>: True" entries. Ugly,
+ # but required by the rest of the pipeline for parsing.
+ for m in parsed.expectations + remaining_modifiers:
+ test_expectation_info[m] = True
+
+ return parsed.name, test_expectation_info
diff --git a/chromium/media/tools/layout_tests/test_expectations_history.py b/chromium/media/tools/layout_tests/test_expectations_history.py
new file mode 100644
index 00000000000..5d03e0fc5c2
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_expectations_history.py
@@ -0,0 +1,128 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A module for the history of the test expectation file."""
+
+from datetime import datetime
+from datetime import timedelta
+
+import os
+import re
+import sys
+import tempfile
+import time
+import pysvn
+
+TEST_EXPECTATIONS_ROOT = 'http://src.chromium.org/blink/trunk/'
+# A map from earliest revision to path.
+# TODO(imasaki): support multiple test expectation files.
+TEST_EXPECTATIONS_LOCATIONS = {
+ 148348: 'LayoutTests/TestExpectations',
+ 119317: 'LayoutTests/platform/chromium/TestExpectations',
+ 0: 'LayoutTests/platform/chromium/test_expectations.txt'}
+TEST_EXPECTATIONS_DEFAULT_PATH = (
+ TEST_EXPECTATIONS_ROOT + TEST_EXPECTATIONS_LOCATIONS[148348])
+
+class TestExpectationsHistory(object):
+ """A class to represent history of the test expectation file.
+
+ The history is obtained by calling PySVN.log()/diff() APIs.
+
+ TODO(imasaki): Add more functionalities here like getting some statistics
+ about the test expectation file.
+ """
+
+ @staticmethod
+ def GetTestExpectationsPathForRevision(revision):
+ for i in sorted(TEST_EXPECTATIONS_LOCATIONS.keys(), reverse=True):
+ if revision >= i:
+ return TEST_EXPECTATIONS_ROOT + TEST_EXPECTATIONS_LOCATIONS[i]
+
+ @staticmethod
+ def GetDiffBetweenTimes(start, end, testname_list,
+ te_location=TEST_EXPECTATIONS_DEFAULT_PATH):
+ """Get difference between time period for the specified test names.
+
+ Given the time period, this method first gets the revision number. Then,
+ it gets the diff for each revision. Finally, it keeps the diff relating to
+ the test names and returns them along with other information about
+ revision.
+
+ Args:
+ start: A timestamp specifying start of the time period to be
+ looked at.
+ end: A timestamp object specifying end of the time period to be
+ looked at.
+ testname_list: A list of strings representing test names of interest.
+ te_location: A location of the test expectation file.
+
+ Returns:
+ A list of tuples (old_rev, new_rev, author, date, message, lines). The
+ |lines| contains the diff of the tests of interest.
+ """
+ temp_directory = tempfile.mkdtemp()
+ test_expectations_path = os.path.join(temp_directory, 'TestExpectations')
+ # Get directory name which is necesary to call PySVN.checkout().
+ te_location_dir = te_location[0:te_location.rindex('/')]
+ client = pysvn.Client()
+ client.checkout(te_location_dir, temp_directory, recurse=False)
+ # PySVN.log() (http://pysvn.tigris.org/docs/pysvn_prog_ref.html
+ # #pysvn_client_log) returns the log messages (including revision
+ # number in chronological order).
+ logs = client.log(test_expectations_path,
+ revision_start=pysvn.Revision(
+ pysvn.opt_revision_kind.date, start),
+ revision_end=pysvn.Revision(
+ pysvn.opt_revision_kind.date, end))
+ result_list = []
+ gobackdays = 1
+ while gobackdays < sys.maxint:
+ goback_start = time.mktime(
+ (datetime.fromtimestamp(start) - (
+ timedelta(days=gobackdays))).timetuple())
+ logs_before_time_period = (
+ client.log(test_expectations_path,
+ revision_start=pysvn.Revision(
+ pysvn.opt_revision_kind.date, goback_start),
+ revision_end=pysvn.Revision(
+ pysvn.opt_revision_kind.date, start)))
+ if logs_before_time_period:
+ # Prepend at the beginning of logs.
+ logs.insert(0, logs_before_time_period[len(logs_before_time_period)-1])
+ break
+ gobackdays *= 2
+
+ for i in xrange(len(logs) - 1):
+ old_rev = logs[i].revision.number
+ new_rev = logs[i + 1].revision.number
+ # Parsing the actual diff.
+
+ new_path = TestExpectationsHistory.GetTestExpectationsPathForRevision(
+ new_rev);
+ old_path = TestExpectationsHistory.GetTestExpectationsPathForRevision(
+ old_rev);
+
+ text = client.diff(temp_directory,
+ url_or_path=old_path,
+ revision1=pysvn.Revision(
+ pysvn.opt_revision_kind.number, old_rev),
+ url_or_path2=new_path,
+ revision2=pysvn.Revision(
+ pysvn.opt_revision_kind.number, new_rev))
+ lines = text.split('\n')
+ target_lines = []
+ for line in lines:
+ for testname in testname_list:
+ matches = re.findall(testname, line)
+ if matches:
+ if line[0] == '+' or line[0] == '-':
+ target_lines.append(line)
+ if target_lines:
+ # Needs to convert to normal date string for presentation.
+ result_list.append((
+ old_rev, new_rev, logs[i + 1].author,
+ datetime.fromtimestamp(
+ logs[i + 1].date).strftime('%Y-%m-%d %H:%M:%S'),
+ logs[i + 1].message, target_lines))
+ return result_list
diff --git a/chromium/media/tools/layout_tests/test_expectations_history_unittest.py b/chromium/media/tools/layout_tests/test_expectations_history_unittest.py
new file mode 100755
index 00000000000..dafc980886c
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_expectations_history_unittest.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from datetime import datetime
+
+import calendar
+import unittest
+
+
+from test_expectations_history import TestExpectationsHistory
+
+
+class TestTestExpectationsHistory(unittest.TestCase):
+ """Unit tests for the TestExpectationsHistory class."""
+
+ def AssertTestName(self, result_list, testname):
+ """Assert test name in the result_list.
+
+ Args:
+ result_list: a result list of tuples returned by
+ |GetDiffBetweenTimesOnly1Diff()|. Each tuple consists of
+ (old_rev, new_rev, author, date, message, lines) where
+ |lines| are the entries in the test expectation file.
+ testname: a testname string.
+
+ Returns:
+ True if the result contains the testname, False otherwise.
+ """
+ for (_, _, _, _, _, lines) in result_list:
+ if any([testname in line for line in lines]):
+ return True
+ return False
+
+ # These tests use the following commit.
+ # commit 235788e3a4fc71342a5c9fefe67ce9537706ce35
+ # Author: rniwa@webkit.org
+ # Date: Sat Aug 20 06:19:11 2011 +0000
+
+ def testGetDiffBetweenTimes(self):
+ ptime = calendar.timegm((2011, 8, 20, 0, 0, 0, 0, 0, 0))
+ ctime = calendar.timegm((2011, 8, 21, 0, 0, 0, 0, 0, 0))
+ testname = 'fast/css/getComputedStyle/computed-style-without-renderer.html'
+ testname_list = [testname]
+ result_list = TestExpectationsHistory.GetDiffBetweenTimes(
+ ptime, ctime, testname_list)
+ self.assertTrue(self.AssertTestName(result_list, testname))
+
+ def testGetDiffBetweenTimesOnly1Diff(self):
+ ptime = calendar.timegm((2011, 8, 20, 6, 0, 0, 0, 0, 0))
+ ctime = calendar.timegm((2011, 8, 20, 7, 0, 0, 0, 0, 0))
+ testname = 'fast/css/getComputedStyle/computed-style-without-renderer.html'
+ testname_list = [testname]
+ result_list = TestExpectationsHistory.GetDiffBetweenTimes(
+ ptime, ctime, testname_list)
+ self.assertTrue(self.AssertTestName(result_list, testname))
+
+ def testGetDiffBetweenTimesOnly1DiffWithGobackSeveralDays(self):
+ ptime = calendar.timegm((2011, 9, 12, 1, 0, 0, 0, 0, 0))
+ ctime = calendar.timegm((2011, 9, 12, 2, 0, 0, 0, 0, 0))
+ testname = 'media/video-zoom-controls.html'
+ testname_list = [testname]
+ result_list = TestExpectationsHistory.GetDiffBetweenTimes(
+ ptime, ctime, testname_list)
+ self.assertTrue(self.AssertTestName(result_list, testname))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/layout_tests/test_expectations_unittest.py b/chromium/media/tools/layout_tests/test_expectations_unittest.py
new file mode 100755
index 00000000000..b5ed2bfc540
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_expectations_unittest.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+from test_expectations import TestExpectations
+
+
+class TestTestExpectations(unittest.TestCase):
+
+ def testParseLine(self):
+ line = ('crbug.com/86714 [ Mac Gpu ] media/video-zoom.html [ Crash '
+ 'ImageOnlyFailure ]')
+ expected_map = {'CRASH': True, 'IMAGE': True, 'Bugs': ['BUGCR86714'],
+ 'Comments': '', 'MAC': True, 'Gpu': True,
+ 'Platforms': ['MAC', 'Gpu']}
+ self.assertEquals(TestExpectations.ParseLine(line),
+ ('media/video-zoom.html', expected_map))
+
+ def testParseLineWithLineComments(self):
+ line = ('crbug.com/86714 [ Mac Gpu ] media/video-zoom.html [ Crash '
+ 'ImageOnlyFailure ] # foo')
+ expected_map = {'CRASH': True, 'IMAGE': True, 'Bugs': ['BUGCR86714'],
+ 'Comments': ' foo', 'MAC': True, 'Gpu': True,
+ 'Platforms': ['MAC', 'Gpu']}
+ self.assertEquals(TestExpectations.ParseLine(line),
+ ('media/video-zoom.html', expected_map))
+
+ def testParseLineWithLineGPUComments(self):
+ line = ('crbug.com/86714 [ Mac ] media/video-zoom.html [ Crash '
+ 'ImageOnlyFailure ] # Gpu')
+ expected_map = {'CRASH': True, 'IMAGE': True, 'Bugs': ['BUGCR86714'],
+ 'Comments': ' Gpu', 'MAC': True,
+ 'Platforms': ['MAC']}
+ self.assertEquals(TestExpectations.ParseLine(line),
+ ('media/video-zoom.html', expected_map))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/layout_tests/testname/media.csv b/chromium/media/tools/layout_tests/testname/media.csv
new file mode 100644
index 00000000000..50569d24820
--- /dev/null
+++ b/chromium/media/tools/layout_tests/testname/media.csv
@@ -0,0 +1,25 @@
+compositing/geometry/clipped-video-controller.html,
+compositing/geometry/video-fixed-scrolling.html,
+compositing/geometry/video-opacity-overlay.html,
+compositing/overflow/overflow-compositing-descendant.html,
+compositing/overflow/scroll-ancestor-update.html,
+compositing/reflections/load-video-in-reflection.html,
+compositing/self-painting-layers.html,
+compositing/self-painting-layers2.html,
+compositing/video/video-background-color.html,
+compositing/video/video-poster.html,
+fast/canvas/webgl/context-lost.html,
+fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html,
+fast/dom/beforeload/remove-video-in-beforeload-listener.html,
+fast/dom/beforeload/video-before-load.html,
+fast/dom/shadow/frameless-media-element-crash.html,
+fast/events/constructors/media-key-event-constructor.html,
+fast/events/constructors/track-event-constructor.html,
+fast/layers/video-layer.html,
+http/tests/appcache/video.html,
+http/tests/canvas/webgl/origin-clean-conformance.html,
+http/tests/media/,
+http/tests/security/\S*video\S+.html,
+http/tests/security/contentSecurityPolicy/media-src-allowed.html,
+http/tests/security/contentSecurityPolicy/media-src-blocked.html,
+media/,
diff --git a/chromium/media/tools/layout_tests/trend_graph.py b/chromium/media/tools/layout_tests/trend_graph.py
new file mode 100644
index 00000000000..f6a8f6f183e
--- /dev/null
+++ b/chromium/media/tools/layout_tests/trend_graph.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A module for manipulating trend graph with analyzer result history."""
+
+import os
+
+import layouttest_analyzer_helpers
+
+DEFAULT_TREND_GRAPH_PATH = os.path.join('graph', 'graph.html')
+
+# The following is necesasry to decide the point to insert.
+LINE_INSERT_POINT_FOR_NUMBERS = r'// insert 1'
+LINE_INSERT_POINT_FOR_PASSING_RATE = r'// insert 2'
+
+
+class TrendGraph(object):
+ """A class to manage trend graph which is using Google Visualization APIs.
+
+ Google Visualization API (http://code.google.com/apis/chart/interactive/docs/
+ gallery/annotatedtimeline.html) is used to present the historical analyzer
+ result. Currently, data is directly written to JavaScript file using file
+ in-place replacement for simplicity.
+
+ TODO(imasaki): use GoogleSpreadsheet to store the analyzer result.
+ """
+
+ def __init__(self, location=DEFAULT_TREND_GRAPH_PATH):
+ """Initialize this object with the location of trend graph."""
+ self._location = location
+
+ def Update(self, datetime_string, data_map):
+ """Update trend graphs using |datetime_string| and |data_map|.
+
+ There are two kinds of graphs to be updated (one is for numbers and the
+ other is for passing rates).
+
+ Args:
+ datetime_string: a datetime string delimited by ','
+ (e.g., '2008,1,1,13,45,00)'. For example, in the case of the year
+ 2008, this ranges from '2008,1,1,0,0,00' to '2008,12,31,23,59,99'.
+ data_map: a dictionary containing 'whole', 'skip' , 'nonskip',
+ 'passingrate' as its keys and (number, tile, text) string tuples
+ as values for graph annotation.
+ """
+ joined_str = ''
+ # For a date format in GViz, month is shifted (e.g., '2008,2,1' means
+ # March 1, 2008). So, the input parameter |datetime_string| (before this
+ # conversion) must be shifted in order to show the date properly on GViz.
+ # After the below conversion, for example, in the case of the year 2008,
+ # |datetime_string| ranges from '2008,0,1,0,0,00' to '2008,11,31,23,59,99'.
+ str_list = datetime_string.split(',')
+ str_list[1] = str(int(str_list[1])-1) # Month
+ datetime_string = ','.join(str_list)
+ for key in ['whole', 'skip', 'nonskip']:
+ joined_str += str(len(data_map[key][0])) + ','
+ joined_str += ','.join(data_map[key][1:]) + ','
+ new_line_for_numbers = ' [new Date(%s),%s],\n' % (datetime_string,
+ joined_str)
+ new_line_for_numbers += ' %s\n' % (
+ LINE_INSERT_POINT_FOR_NUMBERS)
+ layouttest_analyzer_helpers.ReplaceLineInFile(
+ self._location, LINE_INSERT_POINT_FOR_NUMBERS,
+ new_line_for_numbers)
+
+ joined_str = '%s,%s,%s' % (
+ str(data_map['passingrate'][0]), data_map['nonskip'][1],
+ data_map['nonskip'][2])
+ new_line_for_passingrate = ' [new Date(%s),%s],\n' % (
+ datetime_string, joined_str)
+ new_line_for_passingrate += ' %s\n' % (
+ LINE_INSERT_POINT_FOR_PASSING_RATE)
+ layouttest_analyzer_helpers.ReplaceLineInFile(
+ self._location, LINE_INSERT_POINT_FOR_PASSING_RATE,
+ new_line_for_passingrate)
diff --git a/chromium/media/tools/layout_tests/trend_graph_unittest.py b/chromium/media/tools/layout_tests/trend_graph_unittest.py
new file mode 100755
index 00000000000..f866aa6cf02
--- /dev/null
+++ b/chromium/media/tools/layout_tests/trend_graph_unittest.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import shutil
+import unittest
+
+from trend_graph import TrendGraph
+
+
+class TestTrendGraph(unittest.TestCase):
+
+ def testUpdate(self):
+ test_graph_file_backup_path = os.path.join('test_data', 'graph.html.bak')
+ test_graph_file_path = os.path.join('test_data', 'graph.html')
+ shutil.copyfile(test_graph_file_backup_path, test_graph_file_path)
+ trend_graph = TrendGraph(test_graph_file_path)
+ data_map = {}
+ data_map['whole'] = (['test1'], 'undefined', 'undefined')
+ data_map['skip'] = (['test1', 'test2'], 'undefined', 'undefined')
+ data_map['nonskip'] = (['test1', 'test2', 'test3'], 'undefined',
+ 'undefined')
+ data_map['passingrate'] = (str(4), 'undefined', 'undefined')
+
+ trend_graph.Update('2008,1,1,13,45,00', data_map)
+ # Assert the result graph from the file.
+ f = open(test_graph_file_path)
+ lines2 = f.readlines()
+ f.close()
+ line_count = 0
+ for line in lines2:
+ if '2008,0,1,13,45,00' in line:
+ line_count += 1
+ self.assertEqual(line_count, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/media/tools/media_bench/media_bench.cc b/chromium/media/tools/media_bench/media_bench.cc
new file mode 100644
index 00000000000..4214988b6ee
--- /dev/null
+++ b/chromium/media/tools/media_bench/media_bench.cc
@@ -0,0 +1,588 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Standalone benchmarking application based on FFmpeg. This tool is used to
+// measure decoding performance between different FFmpeg compile and run-time
+// options. We also use this tool to measure performance regressions when
+// testing newer builds of FFmpeg from trunk.
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "base/at_exit.h"
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/files/memory_mapped_file.h"
+#include "base/logging.h"
+#include "base/md5.h"
+#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "media/base/djb2.h"
+#include "media/base/media.h"
+#include "media/ffmpeg/ffmpeg_common.h"
+#include "media/filters/ffmpeg_glue.h"
+#include "media/filters/ffmpeg_video_decoder.h"
+#include "media/filters/in_memory_url_protocol.h"
+
+// For pipe _setmode to binary
+#if defined(OS_WIN)
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+namespace switches {
+const char kStream[] = "stream";
+const char kVideoThreads[] = "video-threads";
+const char kFast2[] = "fast2";
+const char kErrorCorrection[] = "error-correction";
+const char kSkip[] = "skip";
+const char kFlush[] = "flush";
+const char kDjb2[] = "djb2";
+const char kMd5[] = "md5";
+const char kFrames[] = "frames";
+const char kLoop[] = "loop";
+
+} // namespace switches
+
+#if defined(OS_WIN)
+
+// Enable to build with exception handler
+// #define ENABLE_WINDOWS_EXCEPTIONS 1
+
+#ifdef ENABLE_WINDOWS_EXCEPTIONS
+// warning: disable warning about exception handler.
+#pragma warning(disable:4509)
+#endif
+
+// Thread priorities to make benchmark more stable.
+
+void EnterTimingSection() {
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
+}
+
+void LeaveTimingSection() {
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
+}
+#else
+void EnterTimingSection() {
+ pthread_attr_t pta;
+ struct sched_param param;
+
+ pthread_attr_init(&pta);
+ memset(&param, 0, sizeof(param));
+ param.sched_priority = 78;
+ pthread_attr_setschedparam(&pta, &param);
+ pthread_attr_destroy(&pta);
+}
+
+void LeaveTimingSection() {
+}
+#endif
+
+int main(int argc, const char** argv) {
+ base::AtExitManager exit_manager;
+
+ CommandLine::Init(argc, argv);
+
+ logging::LoggingSettings settings;
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ logging::InitLogging(settings);
+
+ const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ const CommandLine::StringVector& filenames = cmd_line->GetArgs();
+ if (filenames.empty()) {
+ std::cerr << "Usage: " << argv[0] << " [OPTIONS] FILE [DUMPFILE]\n"
+ << " --stream=[audio|video] "
+ << "Benchmark either the audio or video stream\n"
+ << " --video-threads=N "
+ << "Decode video using N threads\n"
+ << " --frames=N "
+ << "Decode N frames\n"
+ << " --loop=N "
+ << "Loop N times\n"
+ << " --fast2 "
+ << "Enable fast2 flag\n"
+ << " --error-correction "
+ << "Enable ffmpeg error correction\n"
+ << " --flush "
+ << "Flush last frame\n"
+ << " --djb2 (aka --hash) "
+ << "Hash decoded buffers (DJB2)\n"
+ << " --md5 "
+ << "Hash decoded buffers (MD5)\n"
+ << " --skip=[1|2|3] "
+ << "1=loop nonref, 2=loop, 3= frame nonref\n" << std::endl;
+ return 1;
+ }
+
+ // Initialize our media library (try loading DLLs, etc.) before continuing.
+ base::FilePath media_path;
+ PathService::Get(base::DIR_MODULE, &media_path);
+ if (!media::InitializeMediaLibrary(media_path)) {
+ std::cerr << "Unable to initialize the media library." << std::endl;
+ return 1;
+ }
+
+ // Retrieve command line options.
+ base::FilePath in_path(filenames[0]);
+ base::FilePath out_path;
+ if (filenames.size() > 1)
+ out_path = base::FilePath(filenames[1]);
+ AVMediaType target_codec = AVMEDIA_TYPE_UNKNOWN;
+
+ // Determine whether to benchmark audio or video decoding.
+ std::string stream(cmd_line->GetSwitchValueASCII(switches::kStream));
+ if (!stream.empty()) {
+ if (stream.compare("audio") == 0) {
+ target_codec = AVMEDIA_TYPE_AUDIO;
+ } else if (stream.compare("video") == 0) {
+ target_codec = AVMEDIA_TYPE_VIDEO;
+ } else {
+ std::cerr << "Unknown --stream option " << stream << std::endl;
+ return 1;
+ }
+ }
+
+ // Determine number of threads to use for video decoding (optional).
+ int video_threads = 0;
+ std::string threads(cmd_line->GetSwitchValueASCII(switches::kVideoThreads));
+ if (!threads.empty() &&
+ !base::StringToInt(threads, &video_threads)) {
+ video_threads = 0;
+ }
+
+ // Determine number of frames to decode (optional).
+ int max_frames = 0;
+ std::string frames_opt(cmd_line->GetSwitchValueASCII(switches::kFrames));
+ if (!frames_opt.empty() &&
+ !base::StringToInt(frames_opt, &max_frames)) {
+ max_frames = 0;
+ }
+
+ // Determine number of times to loop (optional).
+ int max_loops = 0;
+ std::string loop_opt(cmd_line->GetSwitchValueASCII(switches::kLoop));
+ if (!loop_opt.empty() &&
+ !base::StringToInt(loop_opt, &max_loops)) {
+ max_loops = 0;
+ }
+
+ bool fast2 = false;
+ if (cmd_line->HasSwitch(switches::kFast2)) {
+ fast2 = true;
+ }
+
+ bool error_correction = false;
+ if (cmd_line->HasSwitch(switches::kErrorCorrection)) {
+ error_correction = true;
+ }
+
+ bool flush = false;
+ if (cmd_line->HasSwitch(switches::kFlush)) {
+ flush = true;
+ }
+
+ unsigned int hash_value = 5381u; // Seed for DJB2.
+ bool hash_djb2 = false;
+ if (cmd_line->HasSwitch(switches::kDjb2)) {
+ hash_djb2 = true;
+ }
+
+ base::MD5Context ctx; // Intermediate MD5 data: do not use
+ base::MD5Init(&ctx);
+ bool hash_md5 = false;
+ if (cmd_line->HasSwitch(switches::kMd5))
+ hash_md5 = true;
+
+ int skip = 0;
+ if (cmd_line->HasSwitch(switches::kSkip)) {
+ std::string skip_opt(cmd_line->GetSwitchValueASCII(switches::kSkip));
+ if (!base::StringToInt(skip_opt, &skip)) {
+ skip = 0;
+ }
+ }
+
+ std::ostream* log_out = &std::cout;
+#if defined(ENABLE_WINDOWS_EXCEPTIONS)
+ // Catch exceptions so this tool can be used in automated testing.
+ __try {
+#endif
+
+ base::MemoryMappedFile file_data;
+ file_data.Initialize(in_path);
+ media::InMemoryUrlProtocol protocol(
+ file_data.data(), file_data.length(), false);
+
+ // Register FFmpeg and attempt to open file.
+ media::FFmpegGlue glue(&protocol);
+ if (!glue.OpenContext()) {
+ std::cerr << "Error: Could not open input for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+
+ AVFormatContext* format_context = glue.format_context();
+
+ // Open output file.
+ FILE *output = NULL;
+ if (!out_path.empty()) {
+ // TODO(fbarchard): Add pipe:1 for piping to stderr.
+ if (out_path.value().substr(0, 5) == FILE_PATH_LITERAL("pipe:") ||
+ out_path.value() == FILE_PATH_LITERAL("-")) {
+ output = stdout;
+ log_out = &std::cerr;
+#if defined(OS_WIN)
+ _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ } else {
+ output = file_util::OpenFile(out_path, "wb");
+ }
+ if (!output) {
+ std::cerr << "Error: Could not open output "
+ << out_path.value() << std::endl;
+ return 1;
+ }
+ }
+
+ // Parse a little bit of the stream to fill out the format context.
+ if (avformat_find_stream_info(format_context, NULL) < 0) {
+ std::cerr << "Error: Could not find stream info for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+
+ // Find our target stream.
+ int target_stream = -1;
+ for (size_t i = 0; i < format_context->nb_streams; ++i) {
+ AVCodecContext* codec_context = format_context->streams[i]->codec;
+ AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
+
+ // See if we found our target codec.
+ if (codec_context->codec_type == target_codec && target_stream < 0) {
+ *log_out << "* ";
+ target_stream = i;
+ } else {
+ *log_out << " ";
+ }
+
+ if (!codec || (codec_context->codec_type == AVMEDIA_TYPE_UNKNOWN)) {
+ *log_out << "Stream #" << i << ": Unknown" << std::endl;
+ } else {
+ // Print out stream information
+ *log_out << "Stream #" << i << ": " << codec->name << " ("
+ << codec->long_name << ")" << std::endl;
+ }
+ }
+
+ // Only continue if we found our target stream.
+ if (target_stream < 0) {
+ std::cerr << "Error: Could not find target stream "
+ << target_stream << " for " << in_path.value() << std::endl;
+ return 1;
+ }
+
+ // Prepare FFmpeg structures.
+ AVPacket packet;
+ AVCodecContext* codec_context = format_context->streams[target_stream]->codec;
+ AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
+
+ // Only continue if we found our codec.
+ if (!codec) {
+ std::cerr << "Error: Could not find codec for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+
+ if (skip == 1) {
+ codec_context->skip_loop_filter = AVDISCARD_NONREF;
+ } else if (skip == 2) {
+ codec_context->skip_loop_filter = AVDISCARD_ALL;
+ } else if (skip == 3) {
+ codec_context->skip_loop_filter = AVDISCARD_ALL;
+ codec_context->skip_frame = AVDISCARD_NONREF;
+ }
+ if (fast2) {
+ // Note this flag is no longer necessary for H264 multithreading.
+ codec_context->flags2 |= CODEC_FLAG2_FAST;
+ }
+ if (error_correction) {
+ codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
+ }
+
+ // Initialize threaded decode.
+ if (target_codec == AVMEDIA_TYPE_VIDEO && video_threads > 0) {
+ codec_context->thread_count = video_threads;
+ }
+
+ // Initialize our codec.
+ if (avcodec_open2(codec_context, codec, NULL) < 0) {
+ std::cerr << "Error: Could not open codec "
+ << (codec_context->codec ? codec_context->codec->name : "(NULL)")
+ << " for " << in_path.value() << std::endl;
+ return 1;
+ }
+
+ // Buffer used for audio decoding.
+ scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> audio_frame(
+ avcodec_alloc_frame());
+ if (!audio_frame) {
+ std::cerr << "Error: avcodec_alloc_frame for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+
+ // Buffer used for video decoding.
+ scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> video_frame(
+ avcodec_alloc_frame());
+ if (!video_frame) {
+ std::cerr << "Error: avcodec_alloc_frame for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+
+ // Remember size of video.
+ int video_width = codec_context->width;
+ int video_height = codec_context->height;
+
+ // Stats collector.
+ EnterTimingSection();
+ std::vector<double> decode_times;
+ decode_times.reserve(4096);
+ // Parse through the entire stream until we hit EOF.
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ int frames = 0;
+ int read_result = 0;
+ do {
+ read_result = av_read_frame(format_context, &packet);
+
+ if (read_result < 0) {
+ if (max_loops) {
+ --max_loops;
+ }
+ if (max_loops > 0) {
+ av_seek_frame(format_context, -1, 0, AVSEEK_FLAG_BACKWARD);
+ read_result = 0;
+ continue;
+ }
+ if (flush) {
+ packet.stream_index = target_stream;
+ packet.size = 0;
+ } else {
+ break;
+ }
+ }
+
+ // Only decode packets from our target stream.
+ if (packet.stream_index == target_stream) {
+ int result = -1;
+ if (target_codec == AVMEDIA_TYPE_AUDIO) {
+ int size_out = 0;
+ int got_audio = 0;
+
+ avcodec_get_frame_defaults(audio_frame.get());
+
+ base::TimeTicks decode_start = base::TimeTicks::HighResNow();
+ result = avcodec_decode_audio4(codec_context, audio_frame.get(),
+ &got_audio, &packet);
+ base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start;
+
+ if (got_audio) {
+ size_out = av_samples_get_buffer_size(
+ NULL, codec_context->channels, audio_frame->nb_samples,
+ codec_context->sample_fmt, 1);
+ }
+
+ if (got_audio && size_out) {
+ decode_times.push_back(delta.InMillisecondsF());
+ ++frames;
+ read_result = 0; // Force continuation.
+
+ if (output) {
+ if (fwrite(audio_frame->data[0], 1, size_out, output) !=
+ static_cast<size_t>(size_out)) {
+ std::cerr << "Error: Could not write "
+ << size_out << " bytes for " << in_path.value()
+ << std::endl;
+ return 1;
+ }
+ }
+
+ const uint8* u8_samples =
+ reinterpret_cast<const uint8*>(audio_frame->data[0]);
+ if (hash_djb2) {
+ hash_value = DJB2Hash(u8_samples, size_out, hash_value);
+ }
+ if (hash_md5) {
+ base::MD5Update(
+ &ctx,
+ base::StringPiece(reinterpret_cast<const char*>(u8_samples),
+ size_out));
+ }
+ }
+ } else if (target_codec == AVMEDIA_TYPE_VIDEO) {
+ int got_picture = 0;
+
+ avcodec_get_frame_defaults(video_frame.get());
+
+ base::TimeTicks decode_start = base::TimeTicks::HighResNow();
+ result = avcodec_decode_video2(codec_context, video_frame.get(),
+ &got_picture, &packet);
+ base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start;
+
+ if (got_picture) {
+ decode_times.push_back(delta.InMillisecondsF());
+ ++frames;
+ read_result = 0; // Force continuation.
+
+ for (int plane = 0; plane < 3; ++plane) {
+ const uint8* source = video_frame->data[plane];
+ const size_t source_stride = video_frame->linesize[plane];
+ size_t bytes_per_line = codec_context->width;
+ size_t copy_lines = codec_context->height;
+ if (plane != 0) {
+ switch (codec_context->pix_fmt) {
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_YUVJ420P:
+ bytes_per_line /= 2;
+ copy_lines = (copy_lines + 1) / 2;
+ break;
+ case PIX_FMT_YUV422P:
+ case PIX_FMT_YUVJ422P:
+ bytes_per_line /= 2;
+ break;
+ case PIX_FMT_YUV444P:
+ case PIX_FMT_YUVJ444P:
+ break;
+ default:
+ std::cerr << "Error: Unknown video format "
+ << codec_context->pix_fmt;
+ return 1;
+ }
+ }
+ if (output) {
+ for (size_t i = 0; i < copy_lines; ++i) {
+ if (fwrite(source, 1, bytes_per_line, output) !=
+ bytes_per_line) {
+ std::cerr << "Error: Could not write data after "
+ << copy_lines << " lines for "
+ << in_path.value() << std::endl;
+ return 1;
+ }
+ source += source_stride;
+ }
+ }
+ if (hash_djb2) {
+ for (size_t i = 0; i < copy_lines; ++i) {
+ hash_value = DJB2Hash(source, bytes_per_line, hash_value);
+ source += source_stride;
+ }
+ }
+ if (hash_md5) {
+ for (size_t i = 0; i < copy_lines; ++i) {
+ base::MD5Update(
+ &ctx,
+ base::StringPiece(reinterpret_cast<const char*>(source),
+ bytes_per_line));
+ source += source_stride;
+ }
+ }
+ }
+ }
+ } else {
+ NOTREACHED();
+ }
+
+ // Make sure our decoding went OK.
+ if (result < 0) {
+ std::cerr << "Error: avcodec_decode returned "
+ << result << " for " << in_path.value() << std::endl;
+ return 1;
+ }
+ }
+ // Free our packet.
+ av_free_packet(&packet);
+
+ if (max_frames && (frames >= max_frames))
+ break;
+ } while (read_result >= 0);
+ base::TimeDelta total = base::TimeTicks::HighResNow() - start;
+ LeaveTimingSection();
+
+ // Clean up.
+ if (output)
+ file_util::CloseFile(output);
+
+ // Calculate the sum of times. Note that some of these may be zero.
+ double sum = 0;
+ for (size_t i = 0; i < decode_times.size(); ++i) {
+ sum += decode_times[i];
+ }
+
+ double average = 0;
+ double stddev = 0;
+ double fps = 0;
+ if (frames > 0) {
+ // Calculate the average time per frame.
+ average = sum / frames;
+
+ // Calculate the sum of the squared differences.
+ // Standard deviation will only be accurate if no threads are used.
+ // TODO(fbarchard): Rethink standard deviation calculation.
+ double squared_sum = 0;
+ for (int i = 0; i < frames; ++i) {
+ double difference = decode_times[i] - average;
+ squared_sum += difference * difference;
+ }
+
+ // Calculate the standard deviation (jitter).
+ stddev = sqrt(squared_sum / frames);
+
+ // Calculate frames per second.
+ fps = frames * 1000.0 / sum;
+ }
+
+ // Print our results.
+ log_out->setf(std::ios::fixed);
+ log_out->precision(2);
+ *log_out << std::endl;
+ *log_out << " Frames:" << std::setw(11) << frames << std::endl;
+ *log_out << " Width:" << std::setw(11) << video_width << std::endl;
+ *log_out << " Height:" << std::setw(11) << video_height << std::endl;
+ *log_out << " Total:" << std::setw(11) << total.InMillisecondsF()
+ << " ms" << std::endl;
+ *log_out << " Summation:" << std::setw(11) << sum
+ << " ms" << std::endl;
+ *log_out << " Average:" << std::setw(11) << average
+ << " ms" << std::endl;
+ *log_out << " StdDev:" << std::setw(11) << stddev
+ << " ms" << std::endl;
+ *log_out << " FPS:" << std::setw(11) << fps
+ << std::endl;
+ if (hash_djb2) {
+ *log_out << " DJB2 Hash:" << std::setw(11) << hash_value
+ << " " << in_path.value() << std::endl;
+ }
+ if (hash_md5) {
+ base::MD5Digest digest; // The result of the computation.
+ base::MD5Final(&digest, &ctx);
+ *log_out << " MD5 Hash: " << base::MD5DigestToBase16(digest)
+ << " " << in_path.value() << std::endl;
+ }
+#if defined(ENABLE_WINDOWS_EXCEPTIONS)
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ *log_out << " Exception:" << std::setw(11) << GetExceptionCode()
+ << " " << in_path.value() << std::endl;
+ return 1;
+ }
+#endif
+ CommandLine::Reset();
+ return 0;
+}
diff --git a/chromium/media/tools/player_x11/data_source_logger.cc b/chromium/media/tools/player_x11/data_source_logger.cc
new file mode 100644
index 00000000000..0bc5ded9775
--- /dev/null
+++ b/chromium/media/tools/player_x11/data_source_logger.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "media/tools/player_x11/data_source_logger.h"
+
+static void LogAndRunStopClosure(const base::Closure& closure) {
+ VLOG(1) << "Stop() finished";
+ closure.Run();
+}
+
+static void LogAndRunReadCB(
+ int64 position, int size,
+ const media::DataSource::ReadCB& read_cb, int result) {
+ VLOG(1) << "Read(" << position << ", " << size << ") -> " << result;
+ read_cb.Run(result);
+}
+
+DataSourceLogger::DataSourceLogger(
+ scoped_ptr<media::DataSource> data_source,
+ bool streaming)
+ : data_source_(data_source.Pass()),
+ streaming_(streaming) {
+}
+
+void DataSourceLogger::set_host(media::DataSourceHost* host) {
+ VLOG(1) << "set_host(" << host << ")";
+ data_source_->set_host(host);
+}
+
+void DataSourceLogger::Stop(const base::Closure& closure) {
+ VLOG(1) << "Stop() started";
+ data_source_->Stop(base::Bind(&LogAndRunStopClosure, closure));
+}
+
+void DataSourceLogger::Read(
+ int64 position, int size, uint8* data,
+ const media::DataSource::ReadCB& read_cb) {
+ VLOG(1) << "Read(" << position << ", " << size << ")";
+ data_source_->Read(position, size, data, base::Bind(
+ &LogAndRunReadCB, position, size, read_cb));
+}
+
+bool DataSourceLogger::GetSize(int64* size_out) {
+ bool success = data_source_->GetSize(size_out);
+ VLOG(1) << "GetSize() -> " << (success ? "true" : "false")
+ << ", " << *size_out;
+ return success;
+}
+
+bool DataSourceLogger::IsStreaming() {
+ if (streaming_) {
+ VLOG(1) << "IsStreaming() -> true (overridden)";
+ return true;
+ }
+
+ bool streaming = data_source_->IsStreaming();
+ VLOG(1) << "IsStreaming() -> " << (streaming ? "true" : "false");
+ return streaming;
+}
+
+void DataSourceLogger::SetBitrate(int bitrate) {
+ VLOG(1) << "SetBitrate(" << bitrate << ")";
+ data_source_->SetBitrate(bitrate);
+}
+
+DataSourceLogger::~DataSourceLogger() {}
diff --git a/chromium/media/tools/player_x11/data_source_logger.h b/chromium/media/tools/player_x11/data_source_logger.h
new file mode 100644
index 00000000000..c48d413d5ea
--- /dev/null
+++ b/chromium/media/tools/player_x11/data_source_logger.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_X11_DATA_SOURCE_LOGGER_H_
+#define MEDIA_TOOLS_PLAYER_X11_DATA_SOURCE_LOGGER_H_
+
+#include "media/base/data_source.h"
+
+// Logs all DataSource operations to VLOG(1) for debugging purposes.
+class DataSourceLogger : public media::DataSource {
+ public:
+ // Constructs a DataSourceLogger to log operations against another DataSource.
+ //
+ // |data_source| must be initialized in advance.
+ //
+ // |streaming| when set to true will override the implementation
+ // IsStreaming() to always return true, otherwise it will delegate to
+ // |data_source|.
+ DataSourceLogger(scoped_ptr<DataSource> data_source,
+ bool force_streaming);
+ virtual ~DataSourceLogger();
+
+ // media::DataSource implementation.
+ virtual void set_host(media::DataSourceHost* host) OVERRIDE;
+ virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Read(
+ int64 position, int size, uint8* data,
+ const media::DataSource::ReadCB& read_cb) OVERRIDE;
+ virtual bool GetSize(int64* size_out) OVERRIDE;
+ virtual bool IsStreaming() OVERRIDE;
+ virtual void SetBitrate(int bitrate) OVERRIDE;
+
+ private:
+ scoped_ptr<media::DataSource> data_source_;
+ bool streaming_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataSourceLogger);
+};
+
+#endif // MEDIA_TOOLS_PLAYER_X11_DATA_SOURCE_LOGGER_H_
diff --git a/chromium/media/tools/player_x11/gl_video_renderer.cc b/chromium/media/tools/player_x11/gl_video_renderer.cc
new file mode 100644
index 00000000000..9e508087a0c
--- /dev/null
+++ b/chromium/media/tools/player_x11/gl_video_renderer.cc
@@ -0,0 +1,257 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/player_x11/gl_video_renderer.h"
+
+#include <X11/Xutil.h>
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "media/base/buffers.h"
+#include "media/base/video_frame.h"
+#include "media/base/yuv_convert.h"
+#include "ui/gl/gl_implementation.h"
+
+enum { kNumYUVPlanes = 3 };
+
+static GLXContext InitGLContext(Display* display, Window window) {
+ // Some versions of NVIDIA's GL libGL.so include a broken version of
+ // dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically
+ // load it, and use glew to dynamically resolve symbols.
+ // See http://code.google.com/p/chromium/issues/detail?id=16800
+ if (!InitializeGLBindings(gfx::kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "InitializeGLBindings failed";
+ return NULL;
+ }
+
+ XWindowAttributes attributes;
+ XGetWindowAttributes(display, window, &attributes);
+ XVisualInfo visual_info_template;
+ visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
+ int visual_info_count = 0;
+ XVisualInfo* visual_info_list = XGetVisualInfo(display, VisualIDMask,
+ &visual_info_template,
+ &visual_info_count);
+ GLXContext context = NULL;
+ for (int i = 0; i < visual_info_count && !context; ++i) {
+ context = glXCreateContext(display, visual_info_list + i, 0,
+ True /* Direct rendering */);
+ }
+
+ XFree(visual_info_list);
+ if (!context) {
+ return NULL;
+ }
+
+ if (!glXMakeCurrent(display, window, context)) {
+ glXDestroyContext(display, context);
+ return NULL;
+ }
+
+ return context;
+}
+
+// Matrix used for the YUV to RGB conversion.
+static const float kYUV2RGB[9] = {
+ 1.f, 0.f, 1.403f,
+ 1.f, -.344f, -.714f,
+ 1.f, 1.772f, 0.f,
+};
+
+// Vertices for a full screen quad.
+static const float kVertices[8] = {
+ -1.f, 1.f,
+ -1.f, -1.f,
+ 1.f, 1.f,
+ 1.f, -1.f,
+};
+
+// Texture Coordinates mapping the entire texture.
+static const float kTextureCoords[8] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1,
+};
+
+// Pass-through vertex shader.
+static const char kVertexShader[] =
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec2 in_tc;\n"
+ "\n"
+ "void main() {\n"
+ " interp_tc = in_tc;\n"
+ " gl_Position = in_pos;\n"
+ "}\n";
+
+// YUV to RGB pixel shader. Loads a pixel from each plane and pass through the
+// matrix.
+static const char kFragmentShader[] =
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "uniform sampler2D y_tex;\n"
+ "uniform sampler2D u_tex;\n"
+ "uniform sampler2D v_tex;\n"
+ "uniform mat3 yuv2rgb;\n"
+ "\n"
+ "void main() {\n"
+ " float y = texture2D(y_tex, interp_tc).x;\n"
+ " float u = texture2D(u_tex, interp_tc).r - .5;\n"
+ " float v = texture2D(v_tex, interp_tc).r - .5;\n"
+ " vec3 rgb = yuv2rgb * vec3(y, u, v);\n"
+ " gl_FragColor = vec4(rgb, 1);\n"
+ "}\n";
+
+// Buffer size for compile errors.
+static const unsigned int kErrorSize = 4096;
+
+GlVideoRenderer::GlVideoRenderer(Display* display, Window window)
+ : display_(display),
+ window_(window),
+ gl_context_(NULL) {
+}
+
+GlVideoRenderer::~GlVideoRenderer() {
+ glXMakeCurrent(display_, 0, NULL);
+ glXDestroyContext(display_, gl_context_);
+}
+
+void GlVideoRenderer::Paint(media::VideoFrame* video_frame) {
+ if (!gl_context_)
+ Initialize(video_frame->coded_size(), video_frame->visible_rect());
+
+ // Convert YUV frame to RGB.
+ DCHECK(video_frame->format() == media::VideoFrame::YV12 ||
+ video_frame->format() == media::VideoFrame::YV16);
+ DCHECK(video_frame->stride(media::VideoFrame::kUPlane) ==
+ video_frame->stride(media::VideoFrame::kVPlane));
+
+ if (glXGetCurrentContext() != gl_context_ ||
+ glXGetCurrentDrawable() != window_) {
+ glXMakeCurrent(display_, window_, gl_context_);
+ }
+ for (unsigned int i = 0; i < kNumYUVPlanes; ++i) {
+ unsigned int width = video_frame->stride(i);
+ unsigned int height = video_frame->rows(i);
+ glActiveTexture(GL_TEXTURE0 + i);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, video_frame->stride(i));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0,
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, video_frame->data(i));
+ }
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glXSwapBuffers(display_, window_);
+}
+
+void GlVideoRenderer::Initialize(gfx::Size coded_size, gfx::Rect visible_rect) {
+ CHECK(!gl_context_);
+ LOG(INFO) << "Initializing GL Renderer...";
+
+ // Resize the window to fit that of the video.
+ XResizeWindow(display_, window_, visible_rect.width(), visible_rect.height());
+
+ gl_context_ = InitGLContext(display_, window_);
+ CHECK(gl_context_) << "Failed to initialize GL context";
+
+ // Create 3 textures, one for each plane, and bind them to different
+ // texture units.
+ glGenTextures(3, textures_);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, textures_[2]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
+ GLuint program = glCreateProgram();
+
+ // Create our YUV->RGB shader.
+ GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+ const char* vs_source = kVertexShader;
+ int vs_size = sizeof(kVertexShader);
+ glShaderSource(vertex_shader, 1, &vs_source, &vs_size);
+ glCompileShader(vertex_shader);
+ int result = GL_FALSE;
+ glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &result);
+ if (!result) {
+ char log[kErrorSize];
+ int len = 0;
+ glGetShaderInfoLog(vertex_shader, kErrorSize - 1, &len, log);
+ log[kErrorSize - 1] = 0;
+ LOG(FATAL) << log;
+ }
+ glAttachShader(program, vertex_shader);
+ glDeleteShader(vertex_shader);
+
+ GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+ const char* ps_source = kFragmentShader;
+ int ps_size = sizeof(kFragmentShader);
+ glShaderSource(fragment_shader, 1, &ps_source, &ps_size);
+ glCompileShader(fragment_shader);
+ result = GL_FALSE;
+ glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result);
+ if (!result) {
+ char log[kErrorSize];
+ int len = 0;
+ glGetShaderInfoLog(fragment_shader, kErrorSize - 1, &len, log);
+ log[kErrorSize - 1] = 0;
+ LOG(FATAL) << log;
+ }
+ glAttachShader(program, fragment_shader);
+ glDeleteShader(fragment_shader);
+
+ glLinkProgram(program);
+ result = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &result);
+ if (!result) {
+ char log[kErrorSize];
+ int len = 0;
+ glGetProgramInfoLog(program, kErrorSize - 1, &len, log);
+ log[kErrorSize - 1] = 0;
+ LOG(FATAL) << log;
+ }
+ glUseProgram(program);
+ glDeleteProgram(program);
+
+ // Bind parameters.
+ glUniform1i(glGetUniformLocation(program, "y_tex"), 0);
+ glUniform1i(glGetUniformLocation(program, "u_tex"), 1);
+ glUniform1i(glGetUniformLocation(program, "v_tex"), 2);
+ int yuv2rgb_location = glGetUniformLocation(program, "yuv2rgb");
+ glUniformMatrix3fv(yuv2rgb_location, 1, GL_TRUE, kYUV2RGB);
+
+ int pos_location = glGetAttribLocation(program, "in_pos");
+ glEnableVertexAttribArray(pos_location);
+ glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
+
+ int tc_location = glGetAttribLocation(program, "in_tc");
+ glEnableVertexAttribArray(tc_location);
+ float verts[8];
+ float x0 = static_cast<float>(visible_rect.x()) / coded_size.width();
+ float y0 = static_cast<float>(visible_rect.y()) / coded_size.height();
+ float x1 = static_cast<float>(visible_rect.right()) / coded_size.width();
+ float y1 = static_cast<float>(visible_rect.bottom()) / coded_size.height();
+ verts[0] = x0; verts[1] = y0;
+ verts[2] = x0; verts[3] = y1;
+ verts[4] = x1; verts[5] = y0;
+ verts[6] = x1; verts[7] = y1;
+ glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, verts);
+
+ // We are getting called on a thread. Release the context so that it can be
+ // made current on the main thread.
+ glXMakeCurrent(display_, 0, NULL);
+}
diff --git a/chromium/media/tools/player_x11/gl_video_renderer.h b/chromium/media/tools/player_x11/gl_video_renderer.h
new file mode 100644
index 00000000000..986a51c4799
--- /dev/null
+++ b/chromium/media/tools/player_x11/gl_video_renderer.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_X11_GL_VIDEO_RENDERER_H_
+#define MEDIA_TOOLS_PLAYER_X11_GL_VIDEO_RENDERER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace media {
+class VideoFrame;
+}
+
+class GlVideoRenderer : public base::RefCountedThreadSafe<GlVideoRenderer> {
+ public:
+ GlVideoRenderer(Display* display, Window window);
+
+ void Paint(media::VideoFrame* video_frame);
+
+ private:
+ friend class base::RefCountedThreadSafe<GlVideoRenderer>;
+ ~GlVideoRenderer();
+
+ // Initializes GL rendering for the given dimensions.
+ void Initialize(gfx::Size coded_size, gfx::Rect visible_rect);
+
+ Display* display_;
+ Window window_;
+
+ // GL context.
+ GLXContext gl_context_;
+
+ // 3 textures, one for each plane.
+ GLuint textures_[3];
+
+ DISALLOW_COPY_AND_ASSIGN(GlVideoRenderer);
+};
+
+#endif // MEDIA_TOOLS_PLAYER_X11_GL_VIDEO_RENDERER_H_
diff --git a/chromium/media/tools/player_x11/player_x11.cc b/chromium/media/tools/player_x11/player_x11.cc
new file mode 100644
index 00000000000..cef891247a6
--- /dev/null
+++ b/chromium/media/tools/player_x11/player_x11.cc
@@ -0,0 +1,309 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <signal.h>
+
+#include <iostream> // NOLINT
+
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/threading/platform_thread.h"
+#include "base/threading/thread.h"
+#include "media/audio/audio_manager.h"
+#include "media/audio/null_audio_sink.h"
+#include "media/base/decryptor.h"
+#include "media/base/filter_collection.h"
+#include "media/base/media.h"
+#include "media/base/media_log.h"
+#include "media/base/media_switches.h"
+#include "media/base/pipeline.h"
+#include "media/base/video_frame.h"
+#include "media/filters/audio_renderer_impl.h"
+#include "media/filters/ffmpeg_audio_decoder.h"
+#include "media/filters/ffmpeg_demuxer.h"
+#include "media/filters/ffmpeg_video_decoder.h"
+#include "media/filters/file_data_source.h"
+#include "media/filters/video_renderer_base.h"
+#include "media/tools/player_x11/data_source_logger.h"
+
+// Include X11 headers here because X11/Xlib.h #define's Status
+// which causes compiler errors with Status enum declarations
+// in media::DemuxerStream & media::AudioDecoder.
+#include <X11/XKBlib.h>
+#include <X11/Xlib.h>
+#include "media/tools/player_x11/gl_video_renderer.h"
+#include "media/tools/player_x11/x11_video_renderer.h"
+
+static Display* g_display = NULL;
+static Window g_window = 0;
+static bool g_running = false;
+
+media::AudioManager* g_audio_manager = NULL;
+
+scoped_ptr<media::DataSource> CreateDataSource(const std::string& file_path) {
+ media::FileDataSource* file_data_source = new media::FileDataSource();
+ CHECK(file_data_source->Initialize(base::FilePath(file_path)));
+
+ scoped_ptr<media::DataSource> data_source(file_data_source);
+ return data_source.Pass();
+}
+
+// Initialize X11. Returns true if successful. This method creates the X11
+// window. Further initialization is done in X11VideoRenderer.
+bool InitX11() {
+ g_display = XOpenDisplay(NULL);
+ if (!g_display) {
+ std::cout << "Error - cannot open display" << std::endl;
+ return false;
+ }
+
+ // Get properties of the screen.
+ int screen = DefaultScreen(g_display);
+ int root_window = RootWindow(g_display, screen);
+
+ // Creates the window.
+ g_window = XCreateSimpleWindow(g_display, root_window, 1, 1, 100, 50, 0,
+ BlackPixel(g_display, screen),
+ BlackPixel(g_display, screen));
+ XStoreName(g_display, g_window, "X11 Media Player");
+
+ XSelectInput(g_display, g_window,
+ ExposureMask | ButtonPressMask | KeyPressMask);
+ XMapWindow(g_display, g_window);
+ return true;
+}
+
+void SetOpaque(bool /*opaque*/) {
+}
+
+typedef base::Callback<void(media::VideoFrame*)> PaintCB;
+void Paint(base::MessageLoop* message_loop, const PaintCB& paint_cb,
+ const scoped_refptr<media::VideoFrame>& video_frame) {
+ if (message_loop != base::MessageLoop::current()) {
+ message_loop->PostTask(FROM_HERE, base::Bind(
+ &Paint, message_loop, paint_cb, video_frame));
+ return;
+ }
+
+ paint_cb.Run(video_frame.get());
+}
+
+static void OnBufferingState(media::Pipeline::BufferingState buffering_state) {}
+
+static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data,
+ int init_data_size) {
+ std::cout << "File is encrypted." << std::endl;
+}
+
+static void SaveStatusAndSignal(base::WaitableEvent* event,
+ media::PipelineStatus* status_out,
+ media::PipelineStatus status) {
+ *status_out = status;
+ event->Signal();
+}
+
+// TODO(vrk): Re-enabled audio. (crbug.com/112159)
+void InitPipeline(media::Pipeline* pipeline,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
+ media::Demuxer* demuxer,
+ const PaintCB& paint_cb,
+ bool /* enable_audio */,
+ base::MessageLoop* paint_message_loop) {
+ // Create our filter factories.
+ scoped_ptr<media::FilterCollection> collection(
+ new media::FilterCollection());
+ collection->SetDemuxer(demuxer);
+
+ ScopedVector<media::VideoDecoder> video_decoders;
+ video_decoders.push_back(new media::FFmpegVideoDecoder(message_loop));
+ scoped_ptr<media::VideoRenderer> video_renderer(new media::VideoRendererBase(
+ message_loop,
+ video_decoders.Pass(),
+ media::SetDecryptorReadyCB(),
+ base::Bind(&Paint, paint_message_loop, paint_cb),
+ base::Bind(&SetOpaque),
+ true));
+ collection->SetVideoRenderer(video_renderer.Pass());
+
+ ScopedVector<media::AudioDecoder> audio_decoders;
+ audio_decoders.push_back(new media::FFmpegAudioDecoder(message_loop));
+ scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl(
+ message_loop,
+ new media::NullAudioSink(message_loop),
+ audio_decoders.Pass(),
+ media::SetDecryptorReadyCB(),
+ true));
+ collection->SetAudioRenderer(audio_renderer.Pass());
+
+ base::WaitableEvent event(true, false);
+ media::PipelineStatus status;
+
+ pipeline->Start(
+ collection.Pass(), base::Closure(), media::PipelineStatusCB(),
+ base::Bind(&SaveStatusAndSignal, &event, &status),
+ base::Bind(&OnBufferingState), base::Closure());
+
+ // Wait until the pipeline is fully initialized.
+ event.Wait();
+ CHECK_EQ(status, media::PIPELINE_OK) << "Pipeline initialization failed";
+
+ // And start the playback.
+ pipeline->SetPlaybackRate(1.0f);
+}
+
+void TerminateHandler(int signal) {
+ g_running = false;
+}
+
+void PeriodicalUpdate(
+ media::Pipeline* pipeline,
+ base::MessageLoop* message_loop,
+ bool audio_only) {
+ if (!g_running) {
+ // interrupt signal was received during last time period.
+ // Quit message_loop only when pipeline is fully stopped.
+ pipeline->Stop(base::MessageLoop::QuitClosure());
+ return;
+ }
+
+ // Consume all the X events
+ while (XPending(g_display)) {
+ XEvent e;
+ XNextEvent(g_display, &e);
+ switch (e.type) {
+ case ButtonPress:
+ {
+ Window window;
+ int x, y;
+ unsigned int width, height, border_width, depth;
+ XGetGeometry(g_display,
+ g_window,
+ &window,
+ &x,
+ &y,
+ &width,
+ &height,
+ &border_width,
+ &depth);
+ base::TimeDelta time = pipeline->GetMediaDuration();
+ pipeline->Seek(time*e.xbutton.x/width, media::PipelineStatusCB());
+ }
+ break;
+ case KeyPress:
+ {
+ KeySym key = XkbKeycodeToKeysym(g_display, e.xkey.keycode, 0, 0);
+ if (key == XK_Escape) {
+ g_running = false;
+ // Quit message_loop only when pipeline is fully stopped.
+ pipeline->Stop(base::MessageLoop::QuitClosure());
+ return;
+ } else if (key == XK_space) {
+ if (pipeline->GetPlaybackRate() < 0.01f) // paused
+ pipeline->SetPlaybackRate(1.0f);
+ else
+ pipeline->SetPlaybackRate(0.0f);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ message_loop->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&PeriodicalUpdate,
+ base::Unretained(pipeline),
+ message_loop,
+ audio_only),
+ base::TimeDelta::FromMilliseconds(10));
+}
+
+int main(int argc, char** argv) {
+ base::AtExitManager at_exit;
+ media::InitializeMediaLibraryForTesting();
+
+ CommandLine::Init(argc, argv);
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ std::string filename = command_line->GetSwitchValueASCII("file");
+
+ if (filename.empty()) {
+ std::cout << "Usage: " << argv[0] << " --file=FILE" << std::endl
+ << std::endl
+ << "Optional arguments:" << std::endl
+ << " [--audio]"
+ << " [--alsa-device=DEVICE]"
+ << " [--use-gl]"
+ << " [--streaming]" << std::endl
+ << " Press [ESC] to stop" << std::endl
+ << " Press [SPACE] to toggle pause/play" << std::endl
+ << " Press mouse left button to seek" << std::endl;
+ return 1;
+ }
+
+ scoped_ptr<media::AudioManager> audio_manager(media::AudioManager::Create());
+ g_audio_manager = audio_manager.get();
+
+ logging::LoggingSettings settings;
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ logging::InitLogging(settings);
+
+ // Install the signal handler.
+ signal(SIGTERM, &TerminateHandler);
+ signal(SIGINT, &TerminateHandler);
+
+ // Initialize X11.
+ if (!InitX11())
+ return 1;
+
+ // Initialize the pipeline thread and the pipeline.
+ base::MessageLoop message_loop;
+ base::Thread media_thread("MediaThread");
+ media_thread.Start();
+
+ PaintCB paint_cb;
+ if (command_line->HasSwitch("use-gl")) {
+ paint_cb = base::Bind(
+ &GlVideoRenderer::Paint, new GlVideoRenderer(g_display, g_window));
+ } else {
+ paint_cb = base::Bind(
+ &X11VideoRenderer::Paint, new X11VideoRenderer(g_display, g_window));
+ }
+
+ scoped_ptr<media::DataSource> data_source(new DataSourceLogger(
+ CreateDataSource(filename), command_line->HasSwitch("streaming")));
+ scoped_ptr<media::Demuxer> demuxer(new media::FFmpegDemuxer(
+ media_thread.message_loop_proxy(), data_source.get(),
+ base::Bind(&NeedKey), new media::MediaLog()));
+
+ media::Pipeline pipeline(media_thread.message_loop_proxy(),
+ new media::MediaLog());
+ InitPipeline(&pipeline, media_thread.message_loop_proxy(), demuxer.get(),
+ paint_cb, command_line->HasSwitch("audio"), &message_loop);
+
+ // Main loop of the application.
+ g_running = true;
+
+ message_loop.PostTask(FROM_HERE, base::Bind(
+ &PeriodicalUpdate, base::Unretained(&pipeline), &message_loop,
+ !pipeline.HasVideo()));
+ message_loop.Run();
+
+ // Cleanup tasks.
+ media_thread.Stop();
+
+ // Release callback which releases video renderer. Do this before cleaning up
+ // X below since the video renderer has some X cleanup duties as well.
+ paint_cb.Reset();
+
+ XDestroyWindow(g_display, g_window);
+ XCloseDisplay(g_display);
+ g_audio_manager = NULL;
+
+ return 0;
+}
diff --git a/chromium/media/tools/player_x11/x11_video_renderer.cc b/chromium/media/tools/player_x11/x11_video_renderer.cc
new file mode 100644
index 00000000000..c96d4663e6f
--- /dev/null
+++ b/chromium/media/tools/player_x11/x11_video_renderer.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/player_x11/x11_video_renderer.h"
+
+#include <dlfcn.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xcomposite.h>
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "media/base/video_frame.h"
+#include "media/base/yuv_convert.h"
+
+// Creates a 32-bit XImage.
+static XImage* CreateImage(Display* display, int width, int height) {
+ LOG(INFO) << "Allocating XImage " << width << "x" << height;
+ return XCreateImage(display,
+ DefaultVisual(display, DefaultScreen(display)),
+ DefaultDepth(display, DefaultScreen(display)),
+ ZPixmap,
+ 0,
+ static_cast<char*>(malloc(width * height * 4)),
+ width,
+ height,
+ 32,
+ width * 4);
+}
+
+// Returns the picture format for ARGB.
+// This method is originally from chrome/common/x11_util.cc.
+static XRenderPictFormat* GetRenderARGB32Format(Display* dpy) {
+ static XRenderPictFormat* pictformat = NULL;
+ if (pictformat)
+ return pictformat;
+
+ // First look for a 32-bit format which ignores the alpha value.
+ XRenderPictFormat templ;
+ templ.depth = 32;
+ templ.type = PictTypeDirect;
+ templ.direct.red = 16;
+ templ.direct.green = 8;
+ templ.direct.blue = 0;
+ templ.direct.redMask = 0xff;
+ templ.direct.greenMask = 0xff;
+ templ.direct.blueMask = 0xff;
+ templ.direct.alphaMask = 0;
+
+ static const unsigned long kMask =
+ PictFormatType | PictFormatDepth |
+ PictFormatRed | PictFormatRedMask |
+ PictFormatGreen | PictFormatGreenMask |
+ PictFormatBlue | PictFormatBlueMask |
+ PictFormatAlphaMask;
+
+ pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */);
+
+ if (!pictformat) {
+ // Not all X servers support xRGB32 formats. However, the XRender spec
+ // says that they must support an ARGB32 format, so we can always return
+ // that.
+ pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32);
+ CHECK(pictformat) << "XRender ARGB32 not supported.";
+ }
+
+ return pictformat;
+}
+
+X11VideoRenderer::X11VideoRenderer(Display* display, Window window)
+ : display_(display),
+ window_(window),
+ image_(NULL),
+ picture_(0),
+ use_render_(false) {
+}
+
+X11VideoRenderer::~X11VideoRenderer() {
+ if (image_)
+ XDestroyImage(image_);
+ if (use_render_)
+ XRenderFreePicture(display_, picture_);
+}
+
+void X11VideoRenderer::Paint(media::VideoFrame* video_frame) {
+ if (!image_)
+ Initialize(video_frame->coded_size(), video_frame->visible_rect());
+
+ const int coded_width = video_frame->coded_size().width();
+ const int coded_height = video_frame->coded_size().height();
+ const int visible_width = video_frame->visible_rect().width();
+ const int visible_height = video_frame->visible_rect().height();
+
+ // Check if we need to reallocate our XImage.
+ if (image_->width != coded_width || image_->height != coded_height) {
+ XDestroyImage(image_);
+ image_ = CreateImage(display_, coded_width, coded_height);
+ }
+
+ // Convert YUV frame to RGB.
+ DCHECK(video_frame->format() == media::VideoFrame::YV12 ||
+ video_frame->format() == media::VideoFrame::YV16);
+ DCHECK(video_frame->stride(media::VideoFrame::kUPlane) ==
+ video_frame->stride(media::VideoFrame::kVPlane));
+
+ DCHECK(image_->data);
+ media::YUVType yuv_type =
+ (video_frame->format() == media::VideoFrame::YV12) ?
+ media::YV12 : media::YV16;
+ media::ConvertYUVToRGB32(video_frame->data(media::VideoFrame::kYPlane),
+ video_frame->data(media::VideoFrame::kUPlane),
+ video_frame->data(media::VideoFrame::kVPlane),
+ (uint8*)image_->data, coded_width, coded_height,
+ video_frame->stride(media::VideoFrame::kYPlane),
+ video_frame->stride(media::VideoFrame::kUPlane),
+ image_->bytes_per_line,
+ yuv_type);
+
+ if (use_render_) {
+ // If XRender is used, we'll upload the image to a pixmap. And then
+ // creats a picture from the pixmap and composite the picture over
+ // the picture represending the window.
+
+ // Creates a XImage.
+ XImage image;
+ memset(&image, 0, sizeof(image));
+ image.width = coded_width;
+ image.height = coded_height;
+ image.depth = 32;
+ image.bits_per_pixel = 32;
+ image.format = ZPixmap;
+ image.byte_order = LSBFirst;
+ image.bitmap_unit = 8;
+ image.bitmap_bit_order = LSBFirst;
+ image.bytes_per_line = image_->bytes_per_line;
+ image.red_mask = 0xff;
+ image.green_mask = 0xff00;
+ image.blue_mask = 0xff0000;
+ image.data = image_->data;
+
+ // Creates a pixmap and uploads from the XImage.
+ unsigned long pixmap = XCreatePixmap(display_, window_,
+ visible_width, visible_height,
+ 32);
+ GC gc = XCreateGC(display_, pixmap, 0, NULL);
+ XPutImage(display_, pixmap, gc, &image,
+ video_frame->visible_rect().x(),
+ video_frame->visible_rect().y(),
+ 0, 0,
+ visible_width, visible_height);
+ XFreeGC(display_, gc);
+
+ // Creates the picture representing the pixmap.
+ unsigned long picture = XRenderCreatePicture(
+ display_, pixmap, GetRenderARGB32Format(display_), 0, NULL);
+
+ // Composite the picture over the picture representing the window.
+ XRenderComposite(display_, PictOpSrc, picture, 0,
+ picture_, 0, 0, 0, 0, 0, 0,
+ visible_width, visible_height);
+
+ XRenderFreePicture(display_, picture);
+ XFreePixmap(display_, pixmap);
+ return;
+ }
+
+ // If XRender is not used, simply put the image to the server.
+ // This will have a tearing effect but this is OK.
+ // TODO(hclam): Upload the image to a pixmap and do XCopyArea()
+ // to the window.
+ GC gc = XCreateGC(display_, window_, 0, NULL);
+ XPutImage(display_, window_, gc, image_,
+ video_frame->visible_rect().x(),
+ video_frame->visible_rect().y(),
+ 0, 0, visible_width, visible_height);
+ XFlush(display_);
+ XFreeGC(display_, gc);
+}
+
+void X11VideoRenderer::Initialize(gfx::Size coded_size,
+ gfx::Rect visible_rect) {
+ CHECK(!image_);
+ LOG(INFO) << "Initializing X11 Renderer...";
+
+ // Resize the window to fit that of the video.
+ XResizeWindow(display_, window_, visible_rect.width(), visible_rect.height());
+ image_ = CreateImage(display_, coded_size.width(), coded_size.height());
+
+ // Testing XRender support. We'll use the very basic of XRender
+ // so if it presents it is already good enough. We don't need
+ // to check its version.
+ int dummy;
+ use_render_ = XRenderQueryExtension(display_, &dummy, &dummy);
+
+ if (use_render_) {
+ LOG(INFO) << "Using XRender extension.";
+
+ // If we are using XRender, we'll create a picture representing the
+ // window.
+ XWindowAttributes attr;
+ XGetWindowAttributes(display_, window_, &attr);
+
+ XRenderPictFormat* pictformat = XRenderFindVisualFormat(
+ display_,
+ attr.visual);
+ CHECK(pictformat) << "XRender does not support default visual";
+
+ picture_ = XRenderCreatePicture(display_, window_, pictformat, 0, NULL);
+ CHECK(picture_) << "Backing picture not created";
+ }
+}
diff --git a/chromium/media/tools/player_x11/x11_video_renderer.h b/chromium/media/tools/player_x11/x11_video_renderer.h
new file mode 100644
index 00000000000..3e4b41deadb
--- /dev/null
+++ b/chromium/media/tools/player_x11/x11_video_renderer.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_X11_X11_VIDEO_RENDERER_H_
+#define MEDIA_TOOLS_PLAYER_X11_X11_VIDEO_RENDERER_H_
+
+#include <X11/Xlib.h>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+
+namespace media {
+class VideoFrame;
+}
+
+class X11VideoRenderer : public base::RefCountedThreadSafe<X11VideoRenderer> {
+ public:
+ X11VideoRenderer(Display* display, Window window);
+
+ void Paint(media::VideoFrame* video_frame);
+
+ private:
+ friend class base::RefCountedThreadSafe<X11VideoRenderer>;
+ ~X11VideoRenderer();
+
+ // Initializes X11 rendering for the given dimensions.
+ void Initialize(gfx::Size coded_size, gfx::Rect visible_rect);
+
+ Display* display_;
+ Window window_;
+
+ // Image in heap that contains the RGBA data of the video frame.
+ XImage* image_;
+
+ // Picture represents the paint target. This is a picture located
+ // in the server.
+ unsigned long picture_;
+
+ bool use_render_;
+
+ DISALLOW_COPY_AND_ASSIGN(X11VideoRenderer);
+};
+
+#endif // MEDIA_TOOLS_PLAYER_X11_X11_VIDEO_RENDERER_H_
diff --git a/chromium/media/tools/seek_tester/seek_tester.cc b/chromium/media/tools/seek_tester/seek_tester.cc
new file mode 100644
index 00000000000..d3f6a35044e
--- /dev/null
+++ b/chromium/media/tools/seek_tester/seek_tester.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This standalone binary is a helper for diagnosing seek behavior of the
+// demuxer setup in media/ code. It answers the question: "if I ask the demuxer
+// to Seek to X ms, where will it actually seek to? (necessitating
+// frame-dropping until the original seek target is reached)". Sample run:
+//
+// $ ./out/Debug/seek_tester .../LayoutTests/media/content/test.ogv 6300
+// [0207/130327:INFO:seek_tester.cc(63)] Requested: 6123ms
+// [0207/130327:INFO:seek_tester.cc(68)] audio seeked to: 5526ms
+// [0207/130327:INFO:seek_tester.cc(74)] video seeked to: 5577ms
+
+
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "media/base/media.h"
+#include "media/base/media_log.h"
+#include "media/filters/ffmpeg_demuxer.h"
+#include "media/filters/file_data_source.h"
+
+class DemuxerHostImpl : public media::DemuxerHost {
+ public:
+ // DataSourceHost implementation.
+ virtual void SetTotalBytes(int64 total_bytes) OVERRIDE {}
+ virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE {}
+ virtual void AddBufferedTimeRange(base::TimeDelta start,
+ base::TimeDelta end) OVERRIDE {}
+
+ // DemuxerHost implementation.
+ virtual void SetDuration(base::TimeDelta duration) OVERRIDE {}
+ virtual void OnDemuxerError(media::PipelineStatus error) OVERRIDE {}
+};
+
+void QuitMessageLoop(base::MessageLoop* loop, media::PipelineStatus status) {
+ CHECK_EQ(status, media::PIPELINE_OK);
+ loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+}
+
+void TimestampExtractor(uint64* timestamp_ms,
+ base::MessageLoop* loop,
+ media::DemuxerStream::Status status,
+ const scoped_refptr<media::DecoderBuffer>& buffer) {
+ CHECK_EQ(status, media::DemuxerStream::kOk);
+ if (buffer->timestamp() == media::kNoTimestamp())
+ *timestamp_ms = -1;
+ else
+ *timestamp_ms = buffer->timestamp().InMillisecondsF();
+ loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+}
+
+static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data,
+ int init_data_size) {
+ LOG(INFO) << "File is encrypted.";
+}
+
+int main(int argc, char** argv) {
+ base::AtExitManager at_exit;
+ media::InitializeMediaLibraryForTesting();
+
+ CHECK_EQ(argc, 3) << "\nUsage: " << argv[0] << " <file> <seekTimeInMs>";
+ uint64 seek_target_ms;
+ CHECK(base::StringToUint64(argv[2], &seek_target_ms));
+ scoped_ptr<media::FileDataSource> file_data_source(
+ new media::FileDataSource());
+ CHECK(file_data_source->Initialize(base::FilePath::FromUTF8Unsafe(argv[1])));
+
+ DemuxerHostImpl host;
+ base::MessageLoop loop;
+ media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop);
+ media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
+ scoped_ptr<media::FFmpegDemuxer> demuxer(
+ new media::FFmpegDemuxer(loop.message_loop_proxy(),
+ file_data_source.get(),
+ need_key_cb,
+ new media::MediaLog()));
+ demuxer->Initialize(&host, quitter);
+ loop.Run();
+
+ demuxer->Seek(base::TimeDelta::FromMilliseconds(seek_target_ms), quitter);
+ loop.Run();
+
+ uint64 audio_seeked_to_ms;
+ uint64 video_seeked_to_ms;
+ media::DemuxerStream* audio_stream =
+ demuxer->GetStream(media::DemuxerStream::AUDIO);
+ media::DemuxerStream* video_stream =
+ demuxer->GetStream(media::DemuxerStream::VIDEO);
+ LOG(INFO) << "Requested: " << seek_target_ms << "ms";
+ if (audio_stream) {
+ audio_stream->Read(base::Bind(
+ &TimestampExtractor, &audio_seeked_to_ms, &loop));
+ loop.Run();
+ LOG(INFO) << " audio seeked to: " << audio_seeked_to_ms << "ms";
+ }
+ if (video_stream) {
+ video_stream->Read(
+ base::Bind(&TimestampExtractor, &video_seeked_to_ms, &loop));
+ loop.Run();
+ LOG(INFO) << " video seeked to: " << video_seeked_to_ms << "ms";
+ }
+
+ demuxer->Stop(base::Bind(&base::MessageLoop::Quit, base::Unretained(&loop)));
+ loop.Run();
+
+ return 0;
+}
diff --git a/chromium/media/tools/shader_bench/cpu_color_painter.cc b/chromium/media/tools/shader_bench/cpu_color_painter.cc
new file mode 100644
index 00000000000..a7cb570cdf9
--- /dev/null
+++ b/chromium/media/tools/shader_bench/cpu_color_painter.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/yuv_convert.h"
+#include "media/tools/shader_bench/cpu_color_painter.h"
+
+enum { kNumRGBPlanes = 1 };
+
+// Pass-through vertex shader.
+static const char kVertexShader[] =
+ "precision highp float;\n"
+ "precision highp int;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec2 in_tc;\n"
+ "\n"
+ "void main() {\n"
+ " interp_tc = in_tc;\n"
+ " gl_Position = in_pos;\n"
+ "}\n";
+
+// RGB pixel shader.
+static const char kFragmentShader[] =
+ "precision mediump float;\n"
+ "precision mediump int;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "uniform sampler2D rgba_tex;\n"
+ "\n"
+ "void main() {\n"
+ " vec4 texColor = texture2D(rgba_tex, interp_tc);"
+ " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w);\n"
+ "}\n";
+
+CPUColorPainter::CPUColorPainter()
+ : program_id_(-1) {
+}
+
+CPUColorPainter::~CPUColorPainter() {
+ if (program_id_) {
+ glDeleteProgram(program_id_);
+ glDeleteTextures(kNumRGBPlanes, textures_);
+ }
+}
+
+void CPUColorPainter::Initialize(int width, int height) {
+ glGenTextures(kNumRGBPlanes, textures_);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+ GLuint program = CreateShaderProgram(kVertexShader, kFragmentShader);
+
+ // Bind parameters.
+ glUniform1i(glGetUniformLocation(program, "rgba_tex"), 0);
+ program_id_ = program;
+}
+
+void CPUColorPainter::Paint(scoped_refptr<media::VideoFrame> video_frame) {
+ // Convert to RGB32 frame.
+ scoped_refptr<media::VideoFrame> rgba_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
+ video_frame->coded_size(),
+ video_frame->visible_rect(),
+ video_frame->natural_size(),
+ base::TimeDelta());
+
+ media::ConvertYUVToRGB32(video_frame->data(media::VideoFrame::kYPlane),
+ video_frame->data(media::VideoFrame::kUPlane),
+ video_frame->data(media::VideoFrame::kVPlane),
+ rgba_frame->data(0),
+ video_frame->coded_size().width(),
+ video_frame->coded_size().height(),
+ video_frame->stride(media::VideoFrame::kYPlane),
+ video_frame->stride(media::VideoFrame::kUPlane),
+ rgba_frame->stride(0),
+ media::YV12);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ // Not accounting for x/y offset presently.
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ rgba_frame->visible_rect().width(),
+ rgba_frame->visible_rect().height(),
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ rgba_frame->data(0));
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ surface()->SwapBuffers();
+}
diff --git a/chromium/media/tools/shader_bench/cpu_color_painter.h b/chromium/media/tools/shader_bench/cpu_color_painter.h
new file mode 100644
index 00000000000..7aba3cda861
--- /dev/null
+++ b/chromium/media/tools/shader_bench/cpu_color_painter.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_SHADER_BENCH_CPU_COLOR_PAINTER_H_
+#define MEDIA_TOOLS_SHADER_BENCH_CPU_COLOR_PAINTER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "media/base/video_frame.h"
+#include "media/tools/shader_bench/gpu_painter.h"
+
+// Does color conversion using CPU, rendering on GPU.
+class CPUColorPainter : public GPUPainter {
+ public:
+ CPUColorPainter();
+ virtual ~CPUColorPainter();
+
+ // Painter interface.
+ virtual void Initialize(int width, int height) OVERRIDE;
+ virtual void Paint(scoped_refptr<media::VideoFrame> video_frame) OVERRIDE;
+
+ private:
+ // Shader program id.
+ GLuint program_id_;
+
+ // ID of rgba texture.
+ GLuint textures_[1];
+
+ DISALLOW_COPY_AND_ASSIGN(CPUColorPainter);
+};
+
+#endif // MEDIA_TOOLS_SHADER_BENCH_CPU_COLOR_PAINTER_H_
diff --git a/chromium/media/tools/shader_bench/gpu_color_painter.cc b/chromium/media/tools/shader_bench/gpu_color_painter.cc
new file mode 100644
index 00000000000..17155ee009d
--- /dev/null
+++ b/chromium/media/tools/shader_bench/gpu_color_painter.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/shader_bench/gpu_color_painter.h"
+#include "ui/gl/gl_context.h"
+
+enum { kNumYUVPlanes = 3 };
+
+// Matrix used for the YUV to RGB conversion.
+static const float kYUV2RGB[9] = {
+ 1.f, 0.f, 1.403f,
+ 1.f, -.344f, -.714f,
+ 1.f, 1.772f, 0.f,
+};
+
+static const float kYUV2RGB_TRANS[9] = {
+ 1.f, 1.f, 1.f,
+ 0.f, -.344f, 1.772f,
+ 1.403f, -.714f, 0.f,
+};
+
+// Pass-through vertex shader.
+static const char kVertexShader[] =
+ "precision highp float;\n"
+ "precision highp int;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec2 in_tc;\n"
+ "\n"
+ "void main() {\n"
+ " interp_tc = in_tc;\n"
+ " gl_Position = in_pos;\n"
+ "}\n";
+
+// YUV to RGB pixel shader. Loads a pixel from each plane and pass through the
+// matrix.
+static const char kFragmentShader[] =
+ "precision mediump float;\n"
+ "precision mediump int;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "uniform sampler2D y_tex;\n"
+ "uniform sampler2D u_tex;\n"
+ "uniform sampler2D v_tex;\n"
+ "uniform mat3 yuv2rgb;\n"
+ "\n"
+ "void main() {\n"
+ " float y = texture2D(y_tex, interp_tc).x;\n"
+ " float u = texture2D(u_tex, interp_tc).r - .5;\n"
+ " float v = texture2D(v_tex, interp_tc).r - .5;\n"
+ " vec3 rgb = yuv2rgb * vec3(y, u, v);\n"
+ " gl_FragColor = vec4(rgb, 1);\n"
+ "}\n";
+
+GPUColorWithLuminancePainter::GPUColorWithLuminancePainter()
+ : program_id_(-1) {
+}
+
+GPUColorWithLuminancePainter::~GPUColorWithLuminancePainter() {
+ if (program_id_) {
+ glDeleteProgram(program_id_);
+ glDeleteTextures(kNumYUVPlanes, textures_);
+ }
+}
+
+void GPUColorWithLuminancePainter::Initialize(int width, int height) {
+ // Create 3 textures, one for each plane, and bind them to different
+ // texture units.
+ glGenTextures(kNumYUVPlanes, textures_);
+
+ for (unsigned int i = 0; i < kNumYUVPlanes; ++i) {
+ unsigned int texture_width = (i == media::VideoFrame::kYPlane) ?
+ width : width / 2;
+ unsigned int texture_height = (i == media::VideoFrame::kYPlane) ?
+ height : height / 2;
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(GL_TEXTURE_2D, textures_[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, texture_width, texture_height,
+ 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
+ }
+
+ GLuint program = CreateShaderProgram(kVertexShader, kFragmentShader);
+
+ // Bind parameters.
+ glUniform1i(glGetUniformLocation(program, "y_tex"), 0);
+ glUniform1i(glGetUniformLocation(program, "u_tex"), 1);
+ glUniform1i(glGetUniformLocation(program, "v_tex"), 2);
+ int yuv2rgb_location = glGetUniformLocation(program, "yuv2rgb");
+
+ // DesktopGL supports transpose matrices.
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL)
+ glUniformMatrix3fv(yuv2rgb_location, 1, GL_TRUE, kYUV2RGB);
+ else
+ glUniformMatrix3fv(yuv2rgb_location, 1, GL_FALSE, kYUV2RGB_TRANS);
+
+ program_id_ = program;
+}
+
+void GPUColorWithLuminancePainter::Paint(
+ scoped_refptr<media::VideoFrame> video_frame) {
+ // Not accounting for x/y offset presently.
+ int width = video_frame->visible_rect().width();
+ int height = video_frame->visible_rect().height();
+ for (unsigned int i = 0; i < kNumYUVPlanes; ++i) {
+ unsigned int plane_width =
+ (i == media::VideoFrame::kYPlane) ? width : width / 2;
+ unsigned int plane_height =
+ (i == media::VideoFrame::kYPlane) ? height : height / 2;
+ glBindTexture(GL_TEXTURE_2D, textures_[i]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, plane_width, plane_height,
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, video_frame->data(i));
+ }
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ surface()->SwapBuffers();
+}
diff --git a/chromium/media/tools/shader_bench/gpu_color_painter.h b/chromium/media/tools/shader_bench/gpu_color_painter.h
new file mode 100644
index 00000000000..63c6f52a288
--- /dev/null
+++ b/chromium/media/tools/shader_bench/gpu_color_painter.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_SHADER_BENCH_GPU_COLOR_PAINTER_H_
+#define MEDIA_TOOLS_SHADER_BENCH_GPU_COLOR_PAINTER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "media/base/video_frame.h"
+#include "media/tools/shader_bench/gpu_painter.h"
+#include "ui/gl/gl_context.h"
+
+// Does color space conversion using luminance textures on GPU,
+// renders using GPU.
+class GPUColorWithLuminancePainter : public GPUPainter {
+ public:
+ GPUColorWithLuminancePainter();
+ virtual ~GPUColorWithLuminancePainter();
+
+ // Painter interface.
+ virtual void Initialize(int width, int height) OVERRIDE;
+ virtual void Paint(scoped_refptr<media::VideoFrame> video_frame) OVERRIDE;
+
+ private:
+ // Shader program id.
+ GLuint program_id_;
+
+ // IDs of 3 luminance textures.
+ GLuint textures_[3];
+
+ DISALLOW_COPY_AND_ASSIGN(GPUColorWithLuminancePainter);
+};
+
+#endif // MEDIA_TOOLS_SHADER_BENCH_GPU_COLOR_PAINTER_H_
diff --git a/chromium/media/tools/shader_bench/gpu_painter.cc b/chromium/media/tools/shader_bench/gpu_painter.cc
new file mode 100644
index 00000000000..e6350119307
--- /dev/null
+++ b/chromium/media/tools/shader_bench/gpu_painter.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "media/tools/shader_bench/gpu_painter.h"
+
+// Vertices for a full screen quad.
+static const float kVertices[8] = {
+ -1.f, 1.f,
+ -1.f, -1.f,
+ 1.f, 1.f,
+ 1.f, -1.f,
+};
+
+// Texture Coordinates mapping the entire texture.
+static const float kTextureCoords[8] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1,
+};
+
+// Buffer size for compile errors.
+static const unsigned int kErrorSize = 4096;
+
+GPUPainter::GPUPainter()
+ : surface_(NULL),
+ context_(NULL) {
+}
+
+GPUPainter::~GPUPainter() {
+}
+
+void GPUPainter::SetGLContext(gfx::GLSurface* surface,
+ gfx::GLContext* context) {
+ surface_ = surface;
+ context_ = context;
+}
+
+GLuint GPUPainter::LoadShader(unsigned type, const char* shader_source) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &shader_source, NULL);
+ glCompileShader(shader);
+ int result = GL_FALSE;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
+ if (!result) {
+ char log[kErrorSize];
+ int len;
+ glGetShaderInfoLog(shader, kErrorSize - 1, &len, log);
+ log[kErrorSize - 1] = 0;
+ LOG(FATAL) << "Shader did not compile: " << log;
+ }
+ return shader;
+}
+
+GLuint GPUPainter::CreateShaderProgram(const char* vertex_shader_source,
+ const char* fragment_shader_source) {
+
+ // Create vertex and pixel shaders.
+ GLuint vertex_shader = LoadShader(GL_VERTEX_SHADER, vertex_shader_source);
+ GLuint fragment_shader =
+ LoadShader(GL_FRAGMENT_SHADER, fragment_shader_source);
+
+ // Create program and attach shaders.
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertex_shader);
+ glAttachShader(program, fragment_shader);
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+ glLinkProgram(program);
+ int result = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &result);
+ if (!result) {
+ char log[kErrorSize];
+ int len;
+ glGetProgramInfoLog(program, kErrorSize - 1, &len, log);
+ log[kErrorSize - 1] = 0;
+ LOG(FATAL) << "Program did not link: " << log;
+ }
+ glUseProgram(program);
+
+ // Set common vertex parameters.
+ int pos_location = glGetAttribLocation(program, "in_pos");
+ glEnableVertexAttribArray(pos_location);
+ glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
+
+ int tc_location = glGetAttribLocation(program, "in_tc");
+ glEnableVertexAttribArray(tc_location);
+ glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
+ return program;
+}
diff --git a/chromium/media/tools/shader_bench/gpu_painter.h b/chromium/media/tools/shader_bench/gpu_painter.h
new file mode 100644
index 00000000000..e68305bd000
--- /dev/null
+++ b/chromium/media/tools/shader_bench/gpu_painter.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_SHADER_BENCH_GPU_PAINTER_H_
+#define MEDIA_TOOLS_SHADER_BENCH_GPU_PAINTER_H_
+
+#include "media/tools/shader_bench/painter.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+
+// Class that renders video frames to a window via GPU.
+class GPUPainter : public Painter {
+ public:
+ GPUPainter();
+ virtual ~GPUPainter();
+
+ // Returns a reference to the GL context.
+ gfx::GLSurface* surface() const { return surface_; }
+
+ // Sets context for subsequent gl calls in this painter.
+ virtual void SetGLContext(gfx::GLSurface* surface, gfx::GLContext* context);
+
+ // Creates shader program into given context, from the vertex and fragment
+ // shader source code. Returns the id of the shader program.
+ virtual GLuint CreateShaderProgram(const char* vertex_shader_source,
+ const char* fragment_shader_source);
+
+ private:
+ // Loads shader into given context, from the source code of the
+ // shader. type refers to the shader type, either GL_VERTEX_SHADER or
+ // GL_FRAGMENT_SHADER. Returns id of shader.
+ GLuint LoadShader(unsigned type, const char* shader_source);
+
+ // Reference to the gl context.
+ gfx::GLSurface* surface_;
+ gfx::GLContext* context_;
+
+ DISALLOW_COPY_AND_ASSIGN(GPUPainter);
+};
+
+#endif // MEDIA_TOOLS_SHADER_BENCH_GPU_PAINTER_H_
diff --git a/chromium/media/tools/shader_bench/painter.cc b/chromium/media/tools/shader_bench/painter.cc
new file mode 100644
index 00000000000..ab8fc593473
--- /dev/null
+++ b/chromium/media/tools/shader_bench/painter.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/shader_bench/painter.h"
+
+Painter::Painter()
+ : frames_(NULL) {
+}
+
+Painter::~Painter() {
+}
+
+void Painter::OnPaint() {
+ if (frames_ && !frames_->empty()) {
+ scoped_refptr<media::VideoFrame> cur_frame = frames_->front();
+ Paint(cur_frame);
+ frames_->pop_front();
+ frames_->push_back(cur_frame);
+ }
+}
+
+void Painter::LoadFrames(
+ std::deque<scoped_refptr<media::VideoFrame> >* frames) {
+ frames_ = frames;
+}
diff --git a/chromium/media/tools/shader_bench/painter.h b/chromium/media/tools/shader_bench/painter.h
new file mode 100644
index 00000000000..2dd92ab1248
--- /dev/null
+++ b/chromium/media/tools/shader_bench/painter.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_SHADER_BENCH_PAINTER_H_
+#define MEDIA_TOOLS_SHADER_BENCH_PAINTER_H_
+
+#include <deque>
+
+#include "base/memory/ref_counted.h"
+#include "media/base/video_frame.h"
+
+// Class that paints video frames to a window.
+class Painter {
+ public:
+ Painter();
+ virtual ~Painter();
+
+ // Loads frames into Painter. Painter does not take ownership of frames.
+ virtual void LoadFrames(
+ std::deque<scoped_refptr<media::VideoFrame> >* frames);
+
+ // Called window is ready to be painted.
+ virtual void OnPaint();
+
+ // Initialize a Painter class with a width and a height
+ virtual void Initialize(int width, int height) = 0;
+
+ // Paint a single frame to a window.
+ virtual void Paint(scoped_refptr<media::VideoFrame> video_frame) = 0;
+
+ private:
+ // Frames that the Painter will paint.
+ std::deque<scoped_refptr<media::VideoFrame> >* frames_;
+
+ DISALLOW_COPY_AND_ASSIGN(Painter);
+};
+
+#endif // MEDIA_TOOLS_SHADER_BENCH_PAINTER_H_
diff --git a/chromium/media/tools/shader_bench/shader_bench.cc b/chromium/media/tools/shader_bench/shader_bench.cc
new file mode 100644
index 00000000000..0b4236f1eb1
--- /dev/null
+++ b/chromium/media/tools/shader_bench/shader_bench.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <deque>
+#include <ostream>
+
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "media/base/media.h"
+#include "media/base/video_frame.h"
+#include "media/tools/shader_bench/cpu_color_painter.h"
+#include "media/tools/shader_bench/gpu_color_painter.h"
+#include "media/tools/shader_bench/painter.h"
+#include "media/tools/shader_bench/window.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+
+#if defined(TOOLKIT_GTK)
+#include <gtk/gtk.h>
+#endif
+
+static const int kNumFramesToPaint = 500;
+static base::TimeTicks g_start_;
+static base::TimeTicks g_end_;
+
+long CalculateYUVFrameSize(FILE* file_handle, int num_frames) {
+ fseek(file_handle, 0, SEEK_END);
+ long file_size = (long) ftell(file_handle);
+ rewind(file_handle);
+ return file_size / num_frames;
+}
+
+void GetFrames(std::string file_name,
+ int width, int height, int num_frames,
+ std::deque<scoped_refptr<media::VideoFrame> >& out_frames) {
+ FILE* file_handle = fopen(file_name.c_str(), "rb");
+ if (!file_handle) {
+ printf("Could not open %s\n", file_name.c_str());
+ exit(1);
+ }
+
+ long frame_size = CalculateYUVFrameSize(file_handle, num_frames);
+
+ gfx::Size size(width, height);
+ for (int i = 0; i < num_frames; i++) {
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size,
+ gfx::Rect(size), size,
+ base::TimeDelta());
+ long bytes_read =
+ fread(video_frame->data(0), 1, frame_size, file_handle);
+
+ if (bytes_read != frame_size) {
+ printf("Could not read %s\n", file_name.c_str());
+ fclose(file_handle);
+ exit(1);
+ }
+ out_frames.push_back(video_frame);
+ }
+
+ fclose(file_handle);
+}
+
+void TestFinished() {
+ g_end_ = base::TimeTicks::HighResNow();
+ double time_in_seconds =
+ static_cast<double>((g_end_ - g_start_).InMilliseconds()) / 1000;
+ double fps = kNumFramesToPaint / time_in_seconds;
+ printf("Printed %f frames per second.\n", fps);
+}
+
+void RunTest(media::Window* window, Painter* painter) {
+ g_start_ = base::TimeTicks::HighResNow();
+ window->Start(kNumFramesToPaint, base::Bind(&TestFinished), painter);
+}
+
+int main(int argc, char** argv) {
+ // Read arguments.
+ if (argc == 1) {
+ printf("Usage: %s --file=FILE --wxh=DIMENSIONS --frames=NUM_FRAMES\n"
+ "FILE is a raw .yuv file with 1+ frames in it\n"
+ "DIMENSIONS is the width and height of the frame in pixels\n"
+ "NUM_FRAMES is the number of frames in FILE\n", argv[0]);
+ return 1;
+ }
+
+ // Read command line.
+#if defined(TOOLKIT_GTK)
+ gtk_init(&argc, &argv);
+#endif
+ CommandLine::Init(argc, argv);
+
+ // Determine file name.
+ std::string file_name =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII("file");
+
+ // Determine number of frames.
+ int num_frames = 0;
+ std::string str_num_frames =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII("frames");
+ base::StringToInt(str_num_frames, &num_frames);
+
+ // Determine video dimensions.
+ int width = 0;
+ int height = 0;
+ std::string dimensions =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII("wxh");
+ int x_index = dimensions.find('x');
+ std::string str_width = dimensions.substr(0, x_index);
+ std::string str_height =
+ dimensions.substr(x_index + 1, dimensions.length() - x_index - 1);
+ base::StringToInt(str_width, &width);
+ base::StringToInt(str_height, &height);
+
+ // Process files.
+ std::deque<scoped_refptr<media::VideoFrame> > frames;
+ GetFrames(file_name, width, height, num_frames, frames);
+
+ // Initialize window and graphics context.
+ base::AtExitManager at_exit_manager;
+ media::InitializeMediaLibraryForTesting();
+ gfx::GLSurface::InitializeOneOff();
+ scoped_ptr<media::Window> window(new media::Window(width, height));
+ scoped_refptr<gfx::GLSurface> surface =
+ gfx::GLSurface::CreateViewGLSurface(window->PluginWindow());
+ scoped_refptr<gfx::GLContext> context = gfx::GLContext::CreateGLContext(
+ NULL, surface.get(), gfx::PreferDiscreteGpu);
+ context->MakeCurrent(surface.get());
+ // This sets D3DPRESENT_INTERVAL_IMMEDIATE on Windows.
+ context->SetSwapInterval(0);
+
+ // Initialize and name GPU painters.
+ const struct {
+ const char* name;
+ GPUPainter* painter;
+ } painters[] = {
+ { "CPU CSC + GPU Render", new CPUColorPainter() },
+ { "GPU CSC/Render", new GPUColorWithLuminancePainter() },
+ };
+
+ // Run GPU painter tests.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(painters); i++) {
+ scoped_ptr<GPUPainter> painter(painters[i].painter);
+ painter->LoadFrames(&frames);
+ painter->SetGLContext(surface, context);
+ painter->Initialize(width, height);
+ printf("Running %s tests...", painters[i].name);
+ RunTest(window.get(), painter.get());
+ }
+
+ return 0;
+}
diff --git a/chromium/media/tools/shader_bench/window.cc b/chromium/media/tools/shader_bench/window.cc
new file mode 100644
index 00000000000..3eb26f4d2db
--- /dev/null
+++ b/chromium/media/tools/shader_bench/window.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/shader_bench/window.h"
+
+namespace media {
+
+Window::Window(int width, int height)
+ : painter_(NULL),
+ limit_(0),
+ count_(0),
+ running_(false) {
+ window_handle_ = CreateNativeWindow(width, height);
+}
+
+Window::~Window() {}
+
+} // namespace media
diff --git a/chromium/media/tools/shader_bench/window.h b/chromium/media/tools/shader_bench/window.h
new file mode 100644
index 00000000000..d66e849cd3c
--- /dev/null
+++ b/chromium/media/tools/shader_bench/window.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_TOOLS_SHADER_BENCH_WINDOW_H_
+#define MEDIA_TOOLS_SHADER_BENCH_WINDOW_H_
+
+#include "base/callback.h"
+#include "ui/gfx/native_widget_types.h"
+
+class Painter;
+
+namespace media {
+
+class Window {
+ public:
+ Window(int width, int height);
+ ~Window();
+
+ // Creates and returns a handle to a native window of the given dimensions.
+ gfx::NativeWindow CreateNativeWindow(int width, int height);
+
+ // Returns the NPAPI plugin window handle of the window.
+ gfx::PluginWindowHandle PluginWindow();
+
+ // Kicks off frame painting with the given limit, painter, and
+ // callback to run when painting task is complete.
+ void Start(int limit, const base::Closure& callback, Painter* painter);
+
+ // Called when window is expected to paint self.
+ void OnPaint();
+
+ // Main loop for window.
+ void MainLoop();
+
+ private:
+ // Closure to run when frame painting is completed. Will be reset after
+ // running.
+ base::Closure callback_;
+
+ // Reference to painter Window uses to paint frames.
+ Painter* painter_;
+
+ // Number of frames to paint before closing the window.
+ int limit_;
+
+ // Number of frames currently painted.
+ int count_;
+
+ // True if the window is painting video frames to the screen, false otherwise.
+ bool running_;
+
+ // This window's native handle.
+ gfx::NativeWindow window_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(Window);
+};
+
+} // namespace media
+
+#endif // MEDIA_TOOLS_SHADER_BENCH_WINDOW_H_
diff --git a/chromium/media/tools/shader_bench/window_linux.cc b/chromium/media/tools/shader_bench/window_linux.cc
new file mode 100644
index 00000000000..a0a34932c50
--- /dev/null
+++ b/chromium/media/tools/shader_bench/window_linux.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/shader_bench/window.h"
+
+#include "media/tools/shader_bench/painter.h"
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+namespace media {
+
+static gboolean OnDelete(GtkWidget* widget, GdkEventExpose* event) {
+ gtk_main_quit();
+ return FALSE;
+}
+
+static gboolean OnExpose(GtkWidget* widget,
+ GdkEventExpose* event,
+ gpointer data) {
+ Window* window = reinterpret_cast<Window*>(data);
+ if (window)
+ window->OnPaint();
+ return FALSE;
+}
+
+gfx::NativeWindow Window::CreateNativeWindow(int width, int height) {
+ GtkWidget* hwnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_default_size(GTK_WINDOW(hwnd), width, height);
+ gtk_widget_set_double_buffered(hwnd, FALSE);
+ gtk_widget_set_app_paintable(hwnd, TRUE);
+ gtk_widget_show(hwnd);
+
+ return GTK_WINDOW(hwnd);
+}
+
+gfx::PluginWindowHandle Window::PluginWindow() {
+ return GDK_WINDOW_XWINDOW(GTK_WIDGET(window_handle_)->window);
+}
+
+void Window::Start(int limit, const base::Closure& callback,
+ Painter* painter) {
+ running_ = true;
+ count_ = 0;
+ limit_ = limit;
+ callback_ = callback;
+ painter_ = painter;
+
+ gtk_signal_connect(GTK_OBJECT(window_handle_),
+ "delete_event",
+ reinterpret_cast<GtkSignalFunc>(OnDelete),
+ NULL);
+
+ gtk_signal_connect(GTK_OBJECT(window_handle_),
+ "expose_event",
+ reinterpret_cast<GtkSignalFunc>(OnExpose),
+ this);
+
+ gtk_widget_queue_draw(GTK_WIDGET(window_handle_));
+ MainLoop();
+}
+
+void Window::OnPaint() {
+ if (!running_)
+ return;
+
+ if (count_ < limit_) {
+ painter_->OnPaint();
+ count_++;
+ gtk_widget_queue_draw(GTK_WIDGET(window_handle_));
+ } else {
+ running_ = false;
+ if (!callback_.is_null()) {
+ callback_.Run();
+ callback_.Reset();
+ }
+ gtk_main_quit();
+ }
+}
+
+void Window::MainLoop() {
+ gtk_main();
+}
+
+} // namespace media
diff --git a/chromium/media/tools/shader_bench/window_win.cc b/chromium/media/tools/shader_bench/window_win.cc
new file mode 100644
index 00000000000..abc6fc4e841
--- /dev/null
+++ b/chromium/media/tools/shader_bench/window_win.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/shader_bench/window.h"
+
+#include "media/tools/shader_bench/painter.h"
+
+namespace media {
+
+static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
+ WPARAM w_param, LPARAM l_param) {
+ LRESULT result = 0;
+ switch (msg) {
+ case WM_CLOSE:
+ ::DestroyWindow(hwnd);
+ break;
+ case WM_DESTROY:
+ ::PostQuitMessage(0);
+ break;
+ case WM_ERASEBKGND:
+ // Return a non-zero value to indicate that the background has been
+ // erased.
+ result = 1;
+ break;
+ case WM_PAINT: {
+ Window* window =
+ reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ if (window != NULL)
+ window->OnPaint();
+ ::ValidateRect(hwnd, NULL);
+ break;
+ }
+ default:
+ result = ::DefWindowProc(hwnd, msg, w_param, l_param);
+ break;
+ }
+ return result;
+}
+
+gfx::NativeWindow Window::CreateNativeWindow(int width, int height) {
+ WNDCLASS wnd_class = {0};
+ HINSTANCE instance = GetModuleHandle(NULL);
+ wnd_class.style = CS_OWNDC;
+ wnd_class.lpfnWndProc = WindowProc;
+ wnd_class.hInstance = instance;
+ wnd_class.hbrBackground =
+ reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
+ wnd_class.lpszClassName = L"gpu_demo";
+ if (!RegisterClass(&wnd_class))
+ return NULL;
+
+ DWORD wnd_style = WS_OVERLAPPED | WS_SYSMENU;
+ RECT wnd_rect;
+ wnd_rect.left = 0;
+ wnd_rect.top = 0;
+ wnd_rect.right = width;
+ wnd_rect.bottom = height;
+ AdjustWindowRect(&wnd_rect, wnd_style, FALSE);
+
+ HWND hwnd = CreateWindow(
+ wnd_class.lpszClassName,
+ L"",
+ wnd_style,
+ 0,
+ 0,
+ wnd_rect.right - wnd_rect.left,
+ wnd_rect.bottom - wnd_rect.top,
+ NULL,
+ NULL,
+ instance,
+ NULL);
+ if (hwnd == NULL)
+ return NULL;
+
+ return hwnd;
+}
+
+gfx::PluginWindowHandle Window::PluginWindow() {
+ return window_handle_;
+}
+
+void Window::Start(int limit, const base::Closure& callback,
+ Painter* painter) {
+ running_ = true;
+ count_ = 0;
+ limit_ = limit;
+ callback_ = callback;
+ painter_ = painter;
+
+ SetWindowLongPtr(window_handle_, GWLP_USERDATA,
+ reinterpret_cast<LONG_PTR>(this));
+
+ ShowWindow(window_handle_, SW_SHOWNORMAL);
+
+ // Post first invalidate call to kick off painting.
+ ::InvalidateRect(window_handle_, NULL, FALSE);
+
+ MainLoop();
+}
+
+void Window::OnPaint() {
+ if (!running_)
+ return;
+
+ if (count_ < limit_) {
+ painter_->OnPaint();
+ count_++;
+ } else {
+ running_ = false;
+ if (!callback_.is_null()) {
+ ShowWindow(window_handle_, SW_HIDE);
+ callback_.Run();
+ callback_.Reset();
+ }
+ }
+}
+
+void Window::MainLoop() {
+ MSG msg;
+ bool done = false;
+ while (!done) {
+ while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT || !running_)
+ done = true;
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ if (!done)
+ ::InvalidateRect(window_handle_, NULL, FALSE);
+ }
+ }
+}
+
+} // namespace media