blob: 141688127234863c822d774af1cc4d7e6f4851b4 [file] [log] [blame]
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import sys
import json
import itertools
from typing import Any, List
import unittest
import gpu_path_util
from gpu_tests import common_typing as ct
from gpu_tests import gpu_integration_test
html_path = os.path.join(gpu_path_util.CHROMIUM_SRC_DIR, 'content', 'test',
'data', 'gpu', 'webcodecs')
data_path = os.path.join(gpu_path_util.CHROMIUM_SRC_DIR, 'media', 'test',
'data')
four_colors_img_path = os.path.join(data_path, 'four-colors.y4m')
frame_sources = [
'camera', 'capture', 'offscreen', 'arraybuffer', 'hw_decoder', 'sw_decoder'
]
video_codecs = ['avc1.42001E', 'vp8', 'vp09.00.10.08', 'av01.0.04M.08']
accelerations = ['prefer-hardware', 'prefer-software']
class WebCodecsIntegrationTest(gpu_integration_test.GpuIntegrationTest):
@classmethod
def Name(cls) -> str:
return 'webcodecs'
# pylint: disable=too-many-branches
@classmethod
def GenerateGpuTests(cls, options: ct.ParsedCmdArgs) -> ct.TestGenerator:
tests = itertools.chain(cls.GenerateFrameTests(), cls.GenerateVideoTests(),
cls.GenerateAudioTests())
for test in tests:
yield test
@classmethod
def GenerateFrameTests(cls) -> ct.TestGenerator:
for source_type in frame_sources:
yield ('WebCodecs_DrawImage_' + source_type, 'draw-image.html', [{
'source_type':
source_type
}])
yield ('WebCodecs_TexImage2d_' + source_type, 'tex-image-2d.html', [{
'source_type':
source_type
}])
yield ('WebCodecs_copyTo_' + source_type, 'copyTo.html', [{
'source_type':
source_type
}])
yield ('WebCodecs_GPUExternalTexture_expired_' + source_type,
'gpu-external-texture-expired.html', [{
'source_type': source_type,
'use_worker': False
}])
yield ('WebCodecs_GPUExternalTexture_expired_worker_' + source_type,
'gpu-external-texture-expired.html', [{
'source_type': source_type,
'use_worker': True
}])
yield ('WebCodecs_device_destroy_expired_texture_' + source_type,
'gpu-device-destroy-expire-active-external-texture.html', [{
'source_type':
source_type,
'device_destroyed_before_import':
False
}])
yield ('WebCodecs_texture_expired_from_destroyed_device_' + source_type,
'gpu-device-destroy-expire-active-external-texture.html', [{
'source_type':
source_type,
'device_destroyed_before_import':
True
}])
@classmethod
def GenerateAudioTests(cls) -> ct.TestGenerator:
yield ('WebCodecs_AudioEncoding_AAC_LC', 'audio-encode-decode.html', [{
'codec':
'mp4a.67',
'sample_rate':
48000,
'channels':
2
}])
@classmethod
def GenerateVideoTests(cls) -> ct.TestGenerator:
yield ('WebCodecs_WebRTCPeerConnection_Window',
'webrtc-peer-connection.html', [{
'use_worker': False
}])
yield ('WebCodecs_WebRTCPeerConnection_Worker',
'webrtc-peer-connection.html', [{
'use_worker': True
}])
for source_type in ['offscreen', 'arraybuffer']:
for codec in video_codecs:
for acc in accelerations:
args = (source_type, codec, acc)
yield ('WebCodecs_EncodeDecode_%s_%s_%s' % args, 'encode-decode.html',
[{
'source_type': source_type,
'codec': codec,
'acceleration': acc
}])
for source_type in frame_sources:
for codec in video_codecs:
for acc in accelerations:
args = (source_type, codec, acc)
yield ('WebCodecs_Encode_%s_%s_%s' % args, 'encode.html', [{
'source_type':
source_type,
'codec':
codec,
'acceleration':
acc
}])
for codec in video_codecs:
for acc in accelerations:
for bitrate_mode in ['constant', 'variable']:
for latency_mode in ['realtime', 'quality']:
source_type = 'offscreen'
args = (source_type, codec, acc, bitrate_mode, latency_mode)
yield ('WebCodecs_EncodingModes_%s_%s_%s_%s_%s' % args,
'encoding-modes.html', [{
'source_type': source_type,
'codec': codec,
'acceleration': acc,
'bitrate_mode': bitrate_mode,
'latency_mode': latency_mode
}])
for codec in video_codecs:
for layers in [2, 3]:
args = (codec, layers)
yield ('WebCodecs_SVC_%s_layers_%d' % args, 'svc.html', [{
'codec':
codec,
'layers':
layers
}])
for codec in video_codecs:
for acc in accelerations:
args = (codec, acc)
yield ('WebCodecs_EncodeColorSpace_%s_%s' % args,
'encode-color-space.html', [{
'codec': codec,
'acceleration': acc
}])
# pylint: enable=too-many-branches
def RunActualGpuTest(self, test_path: str, args: ct.TestArgs) -> None:
url = self.UrlOfStaticFilePath(html_path + '/' + test_path)
tab = self.tab
arg_obj = args[0]
os_name = self.platform.GetOSName()
arg_obj['validate_camera_frames'] = self.CameraCanShowFourColors(os_name)
tab.Navigate(url)
tab.action_runner.WaitForJavaScriptCondition(
'document.readyState == "complete"')
tab.EvaluateJavaScript('TEST.run(' + json.dumps(arg_obj) + ')')
tab.action_runner.WaitForJavaScriptCondition('TEST.finished', timeout=60)
if tab.EvaluateJavaScript('TEST.skipped'):
self.skipTest('Skipping test:' + tab.EvaluateJavaScript('TEST.summary()'))
if not tab.EvaluateJavaScript('TEST.success'):
self.fail('Test failure:' + tab.EvaluateJavaScript('TEST.summary()'))
@staticmethod
def CameraCanShowFourColors(os_name: str) -> bool:
return os_name not in ('android', 'chromeos')
@classmethod
def SetUpProcess(cls) -> None:
super(WebCodecsIntegrationTest, cls).SetUpProcess()
args = [
'--use-fake-device-for-media-stream', '--use-fake-ui-for-media-stream',
'--enable-unsafe-webgpu'
]
# If we don't call CustomizeBrowserArgs cls.platform is None
cls.CustomizeBrowserArgs(args)
platform = cls.platform
if cls.CameraCanShowFourColors(platform.GetOSName()):
args.append('--use-file-for-fake-video-capture=' + four_colors_img_path)
cls.CustomizeBrowserArgs(args)
cls.StartBrowser()
cls.SetStaticServerDirs([html_path, data_path])
@classmethod
def ExpectationsFiles(cls) -> List[str]:
return [
os.path.join(os.path.dirname(os.path.abspath(__file__)),
'test_expectations', 'webcodecs_expectations.txt')
]
def load_tests(loader: unittest.TestLoader, tests: Any,
pattern: Any) -> unittest.TestSuite:
del loader, tests, pattern # Unused.
return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])