Commit fd43f186 authored by Jordan Bayles's avatar Jordan Bayles Committed by Commit Bot

Fix CastV2PerformanceTest.Performance

This patch reenables the above test, as well as rewriting it to
no longer depend on the removed cast.streaming extension APIs and
moving it out of the extensions test folder path.

The performance test now performs the offer answer exchange and sets up
the receiver with the SSRC and AES key information from the OFFER. The
video embedded in the test has been moved to being generated in
JavaScript instead of native C++, fixing some playback issues.

This patch also readds a missing ConsumeVideoFrame trace event.

Note: to run the performance test use the following command:

./out/Default/browser_tests --gtest_filter="*CastV2PerformanceTest*" --full-performance-run --vmodule="*udp_transport_impl*=2,*performance_test.cc=2"

Bug: 974427
Change-Id: I73c90d3005e0f2c0bc66453c3585f246651bab7f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2288636Reviewed-by: default avatarChristian Fremerey <chfremer@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Reviewed-by: default avatarTakumi Fujimoto <takumif@chromium.org>
Commit-Queue: Jordan Bayles <jophba@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806348}
parent 9425c0f9
miu@chromium.org
mfoltz@chromium.org
# COMPONENT: Internals>Cast>Streaming
...@@ -14,6 +14,10 @@ include_rules = [ ...@@ -14,6 +14,10 @@ include_rules = [
] ]
specific_include_rules = { specific_include_rules = {
"cast_mirroring_performance_browsertest\.cc": [
"+third_party/openscreen/src/cast/streaming",
"+third_party/jsoncpp/source/include/json",
],
"cast_remoting_connector\.cc": [ "cast_remoting_connector\.cc": [
"+chrome/browser/ui/views/media_router/media_remoting_dialog_view.h", "+chrome/browser/ui/views/media_router/media_remoting_dialog_view.h",
], ],
......
...@@ -82,6 +82,8 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost, ...@@ -82,6 +82,8 @@ class CastMirroringServiceHost final : public mojom::MirroringServiceHost,
friend class CastMirroringServiceHostBrowserTest; friend class CastMirroringServiceHostBrowserTest;
FRIEND_TEST_ALL_PREFIXES(CastMirroringServiceHostTest, FRIEND_TEST_ALL_PREFIXES(CastMirroringServiceHostTest,
TestGetClampedResolution); TestGetClampedResolution);
friend class CastV2PerformanceTest;
FRIEND_TEST_ALL_PREFIXES(CastV2PerformanceTest, Performance);
static gfx::Size GetCaptureResolutionConstraint(); static gfx::Size GetCaptureResolutionConstraint();
// Clamp resolution constraint to the screen size. // Clamp resolution constraint to the screen size.
......
...@@ -790,6 +790,7 @@ if (!is_android) { ...@@ -790,6 +790,7 @@ if (!is_android) {
"//third_party/blink/public:buildflags", "//third_party/blink/public:buildflags",
"//third_party/icu", "//third_party/icu",
"//third_party/leveldatabase", "//third_party/leveldatabase",
"//third_party/openscreen/src/cast/streaming:common",
"//third_party/webrtc_overrides:webrtc_component", "//third_party/webrtc_overrides:webrtc_component",
"//third_party/widevine/cdm:buildflags", "//third_party/widevine/cdm:buildflags",
"//third_party/widevine/cdm:headers", "//third_party/widevine/cdm:headers",
...@@ -1005,6 +1006,7 @@ if (!is_android) { ...@@ -1005,6 +1006,7 @@ if (!is_android) {
"../browser/locale_tests_browsertest.cc", "../browser/locale_tests_browsertest.cc",
"../browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc", "../browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc",
"../browser/media/autoplay_metrics_browsertest.cc", "../browser/media/autoplay_metrics_browsertest.cc",
"../browser/media/cast_mirroring_performance_browsertest.cc",
"../browser/media/cast_mirroring_service_host_browsertest.cc", "../browser/media/cast_mirroring_service_host_browsertest.cc",
"../browser/media/defer_background_media_browsertest.cc", "../browser/media/defer_background_media_browsertest.cc",
"../browser/media/encrypted_media_browsertest.cc", "../browser/media/encrypted_media_browsertest.cc",
...@@ -1775,7 +1777,6 @@ if (!is_android) { ...@@ -1775,7 +1777,6 @@ if (!is_android) {
"../browser/extensions/api/braille_display_private/mock_braille_controller.cc", "../browser/extensions/api/braille_display_private/mock_braille_controller.cc",
"../browser/extensions/api/braille_display_private/mock_braille_controller.h", "../browser/extensions/api/braille_display_private/mock_braille_controller.h",
"../browser/extensions/api/browsing_data/browsing_data_test.cc", "../browser/extensions/api/browsing_data/browsing_data_test.cc",
"../browser/extensions/api/cast_streaming/performance_test.cc",
"../browser/extensions/api/command_line_private/command_line_private_apitest.cc", "../browser/extensions/api/command_line_private/command_line_private_apitest.cc",
"../browser/extensions/api/commands/command_service_browsertest.cc", "../browser/extensions/api/commands/command_service_browsertest.cc",
"../browser/extensions/api/content_settings/content_settings_apitest.cc", "../browser/extensions/api/content_settings/content_settings_apitest.cc",
......
...@@ -33,7 +33,11 @@ mojom("web_ui_test_bindings") { ...@@ -33,7 +33,11 @@ mojom("web_ui_test_bindings") {
} }
group("closure_compile") { group("closure_compile") {
deps = [ ":closure_compile_local" ] deps = [
":closure_compile_local",
"cast:closure_compile",
]
if (enable_pdf) { if (enable_pdf) {
deps += [ "pdf:closure_compile" ] deps += [ "pdf:closure_compile" ]
} }
...@@ -43,7 +47,10 @@ group("closure_compile") { ...@@ -43,7 +47,10 @@ group("closure_compile") {
} }
js_type_check("closure_compile_local") { js_type_check("closure_compile_local") {
deps = [ ":test_api_js" ] deps = [
":test_api_js",
"cast",
]
} }
js_library("test_api_js") { js_library("test_api_js") {
......
# Copyright 2020 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("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [ ":cast" ]
}
# Although not used as a library in practice, marking the browser test this
# way allows for us to get type checking.
js_library("cast") {
sources = [ "cast_mirroring_performance_browsertest.js" ]
}
/* Copyright 2020 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.
*/
body {
background-color: #ffffff;
margin: 0;
padding: 0;
}
div.help,
canvas {
position: absolute;
top: 0vh;
border: none;
margin: none;
padding: none;
}
div.help {
left: 0vw;
}
canvas {
left: 22vw;
width: 56vw;
height: 100vh;
image-rendering: pixelated;
}
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Page for Cast Mirroring Performance Test</title>
<link rel="stylesheet" href="cast_mirroring_performance_browsertest.css">
</head>
<body id="mainBody">
<div id="help">
Click anywhere to start.
<h1>WARNING: Take off headphones or suffer!</h1>
</div>
<canvas id="canvas"/>
</body>
<script src="cast_mirroring_performance_browsertest.js"></script>
</html>
// Copyright 2020 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.
function startBarcodeAnimation() {
const RUN_LENGTH_SECONDS = 30;
const audioContext = new AudioContext();
const audioSource = audioContext.createBufferSource();
const audioBuffer = audioContext.createBuffer(
1, audioContext.sampleRate * RUN_LENGTH_SECONDS, audioContext.sampleRate);
// Renders a barcode representation of the given |frameNumber| to the
// canvas. The barcode is drawn as follows:
//
// #### #### ######## #### ... #### ####
// #### #### ######## #### ... #### ####
// #### #### ######## #### ... #### ####
// #### #### ######## #### ... #### ####
// 0 1 2 3 4 5 6 7 8 9 ... 52 53 54 55
// <-----start----><--one-bit-><-zero bit-> ... <----stop---->
//
// We use a basic unit, depicted here as four characters wide. We start
// with 1u black 1u white 1u black 1u white. (1-4 above) From there on, a
// "one" bit is encoded as 2u black and 1u white, and a zero bit is
// encoded as 1u black and 2u white. After all the bits we end the pattern
// with the same pattern as the start of the pattern.
//
// Only the lower 16 bits of frameNumber are drawn.
const NUM_BARCODE_BITS = 16;
const CANVAS_WIDTH = 4 + NUM_BARCODE_BITS * 3 + 4; // 56.
const CANVAS_HEIGHT = 1;
let lastFrameNumberRendered = null;
function renderBarcodeToCanvas(frameNumber) {
const ctx = document.getElementById('canvas').getContext('2d');
if (lastFrameNumberRendered === null) {
lastFrameNumberRendered = ~frameNumber;
}
for (let bitIndex = 0; bitIndex < NUM_BARCODE_BITS; ++bitIndex) {
const mask = 1 << bitIndex;
if ((lastFrameNumberRendered & mask) == (frameNumber & mask)) {
continue;
}
// Flip a column of pixels from black to white or white to black
// to effectively flip the bit in the barcode.
ctx.fillStyle = (frameNumber & mask) ? '#000000' : '#ffffff';
ctx.fillRect(bitIndex * 3 + 5, 0, 1, 1);
}
lastFrameNumberRendered = frameNumber;
}
const FRAMES_PER_SECOND = 60;
const MILLISECONDS_PER_SECOND = 1000;
let firstFrameTime = null;
let currentFrameNumber = -1;
function drawNextVideoFrame(timestamp) {
if (timestamp >= firstFrameTime) {
const elapsedSeconds =
(timestamp - firstFrameTime) / MILLISECONDS_PER_SECOND;
const frameNumber = Math.trunc(elapsedSeconds * FRAMES_PER_SECOND);
if (frameNumber != currentFrameNumber) {
currentFrameNumber = frameNumber;
renderBarcodeToCanvas(frameNumber);
}
}
requestAnimationFrame(drawNextVideoFrame);
}
/**
* @suppress {missingProperties}
*/
function startSynchronized(timestamp) {
const outputTime = audioContext.getOutputTimestamp();
if (!outputTime.performanceTime) {
// Audio output has not yet begun pumping data. Try again later.
requestAnimationFrame(startSynchronized);
return;
}
firstFrameTime = outputTime.performanceTime;
requestAnimationFrame(drawNextVideoFrame);
}
if (audioSource.buffer !== null) { // Already started?
return;
}
document.getElementById('help').style.display = 'none';
// Set up canvas graphics parameters and render barcode for frame 0.
const canvas = document.getElementById('canvas');
canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;
const ctx = canvas.getContext('2d');
ctx.filter = 'none';
ctx.imageSmoothingEnabled = false;
ctx.fillStyle = '#ffffff';
ctx.fill();
// Start/Stop sequence bars.
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, 1, 1);
ctx.fillRect(2, 0, 1, 1);
ctx.fillRect(CANVAS_WIDTH - 4, 0, 1, 1);
ctx.fillRect(CANVAS_WIDTH - 2, 0, 1, 1);
// Bars representing all bits set to zero.
for (let x = 4; x < 52; x += 3) {
ctx.fillRect(x, 0, 1, 1);
}
// Populate audio barcodes, as a 16-bit number. Based on EncodeTimestamp
// function from media/cast/test/utility/audio_utility.cc.
const BASE_FREQUENCY = 200.0;
const TWO_PI_OVER_BASE_FREQUENCY = 2.0 * Math.PI / audioBuffer.sampleRate;
const channelData = audioBuffer.getChannelData(0);
let i = 0;
for (let frameNumber = 0; i < channelData.length; ++frameNumber) {
// Gray-code the frameNumber.
const code = (frameNumber >> 1) ^ frameNumber;
// Determine which sine waves to render.
const SENSE_FREQUENCY = BASE_FREQUENCY * (NUM_BARCODE_BITS + 1);
let freqs = [SENSE_FREQUENCY];
for (let j = 0; j < NUM_BARCODE_BITS; ++j) {
if ((code >> j) & 1) {
freqs.push(BASE_FREQUENCY * (j + 1));
}
}
// Determine the index after the last sample to be rendered.
const end = Math.min(
Math.round(
((frameNumber + 1) / FRAMES_PER_SECOND) * audioBuffer.sampleRate),
channelData.length);
// Render the samples by mixing the selected sine waves.
for (; i < end; ++i) {
let sample = 0.0;
for (let j = 0; j < freqs.length; ++j) {
sample += Math.sin(TWO_PI_OVER_BASE_FREQUENCY * i * freqs[j]);
}
sample /= NUM_BARCODE_BITS + 1; // Normalize to [-1.0,1.0].
channelData[i] = sample;
}
}
audioSource.buffer = audioBuffer;
audioSource.connect(audioContext.destination);
audioSource.start();
requestAnimationFrame(startSynchronized);
}
document.getElementById('mainBody').addEventListener('click', function() {
startBarcodeAnimation();
});
\ No newline at end of file
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h" #include "base/values.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/cast/cast_config.h" #include "media/cast/cast_config.h"
...@@ -77,6 +78,13 @@ void VideoRtpStream::InsertVideoFrame( ...@@ -77,6 +78,13 @@ void VideoRtpStream::InsertVideoFrame(
client_->OnError("Incompatible video frame format."); client_->OnError("Incompatible video frame format.");
return; return;
} }
// Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "ConsumeVideoFrame",
TRACE_EVENT_SCOPE_THREAD, "timestamp",
(reference_time - base::TimeTicks()).InMicroseconds(),
"time_delta", video_frame->timestamp().InMicroseconds());
video_sender_->InsertRawVideoFrame(std::move(video_frame), reference_time); video_sender_->InsertRawVideoFrame(std::move(video_frame), reference_time);
} }
......
...@@ -161,7 +161,7 @@ void VideoCaptureClient::OnBufferReady(int32_t buffer_id, ...@@ -161,7 +161,7 @@ void VideoCaptureClient::OnBufferReady(int32_t buffer_id,
if (info->timestamp.is_zero()) if (info->timestamp.is_zero())
info->timestamp = reference_time - first_frame_ref_time_; info->timestamp = reference_time - first_frame_ref_time_;
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived", TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived",
TRACE_EVENT_SCOPE_THREAD, "timestamp", TRACE_EVENT_SCOPE_THREAD, "timestamp",
(reference_time - base::TimeTicks()).InMicroseconds(), (reference_time - base::TimeTicks()).InMicroseconds(),
......
...@@ -131,7 +131,7 @@ void CastReceiverImpl::DecodeEncodedVideoFrame( ...@@ -131,7 +131,7 @@ void CastReceiverImpl::DecodeEncodedVideoFrame(
return; return;
} }
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT1("cast_perf_test", "PullEncodedVideoFrame", TRACE_EVENT_INSTANT1("cast_perf_test", "PullEncodedVideoFrame",
TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp",
encoded_frame->rtp_timestamp.lower_32_bits()); encoded_frame->rtp_timestamp.lower_32_bits());
...@@ -199,7 +199,7 @@ void CastReceiverImpl::EmitDecodedVideoFrame( ...@@ -199,7 +199,7 @@ void CastReceiverImpl::EmitDecodedVideoFrame(
playout_event->delay_delta = playout_time - playout_event->timestamp; playout_event->delay_delta = playout_time - playout_event->timestamp;
cast_environment->logger()->DispatchFrameEvent(std::move(playout_event)); cast_environment->logger()->DispatchFrameEvent(std::move(playout_event));
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "VideoFrameDecoded", TRACE_EVENT_INSTANT2("cast_perf_test", "VideoFrameDecoded",
TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp",
rtp_timestamp.lower_32_bits(), "playout_time", rtp_timestamp.lower_32_bits(), "playout_time",
......
...@@ -294,7 +294,7 @@ void FrameSender::SendEncodedFrame( ...@@ -294,7 +294,7 @@ void FrameSender::SendEncodedFrame(
encoded_frame->rtp_timestamp); encoded_frame->rtp_timestamp);
if (!is_audio_) { if (!is_audio_) {
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT1( TRACE_EVENT_INSTANT1(
"cast_perf_test", "VideoFrameEncoded", "cast_perf_test", "VideoFrameEncoded",
TRACE_EVENT_SCOPE_THREAD, TRACE_EVENT_SCOPE_THREAD,
......
...@@ -141,7 +141,7 @@ void VideoSender::InsertRawVideoFrame( ...@@ -141,7 +141,7 @@ void VideoSender::InsertRawVideoFrame(
LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame, LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame,
rtp_timestamp); rtp_timestamp);
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "InsertRawVideoFrame", TRACE_EVENT_INSTANT2("cast_perf_test", "InsertRawVideoFrame",
TRACE_EVENT_SCOPE_THREAD, "timestamp", TRACE_EVENT_SCOPE_THREAD, "timestamp",
(reference_time - base::TimeTicks()).InMicroseconds(), (reference_time - base::TimeTicks()).InMicroseconds(),
......
...@@ -536,7 +536,7 @@ void VideoCaptureImpl::OnBufferReady( ...@@ -536,7 +536,7 @@ void VideoCaptureImpl::OnBufferReady(
// TODO(qiangchen): Change the metric name to "reference_time" and // TODO(qiangchen): Change the metric name to "reference_time" and
// "timestamp", so that we have consistent naming everywhere. // "timestamp", so that we have consistent naming everywhere.
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc // Used by chrome/browser/media/cast_mirroring_performance_browsertest.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived", TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived",
TRACE_EVENT_SCOPE_THREAD, "timestamp", TRACE_EVENT_SCOPE_THREAD, "timestamp",
(reference_time - base::TimeTicks()).InMicroseconds(), (reference_time - base::TimeTicks()).InMicroseconds(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment