1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
content / browser / devtools / devtools_video_consumer_browsertest.cc [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "base/functional/bind.h"
#include "content/browser/devtools/devtools_video_consumer.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
namespace {
// Helper to verify that |frame| dimensions are in the expected ranges.
bool VerifyFrameSize(scoped_refptr<media::VideoFrame> frame,
gfx::Size min_frame_size,
gfx::Size max_frame_size) {
// Returns true if |min_frame_size| <= |frame| <= |max_frame_size|.
return min_frame_size.width() <= frame->visible_rect().width() &&
min_frame_size.height() <= frame->visible_rect().height() &&
frame->visible_rect().width() <= max_frame_size.width() &&
frame->visible_rect().height() <= max_frame_size.height();
}
// The default video pixel format.
// TODO(sundarrajs): Add |FrameSinkVideoCapturerImpl::kDefaultPixelFormat| to
// frame_sink_video_capture.mojom and use that instead of
// |kVideoCapturerDefaultPixelFormat|.
constexpr media::VideoPixelFormat kVideoCapturerDefaultPixelFormat =
media::PIXEL_FORMAT_I420;
} // namespace
namespace content {
class DevToolsVideoConsumerTest : public ContentBrowserTest {
public:
DevToolsVideoConsumerTest() {}
void SetUpOnMainThread() override {
consumer_ = std::make_unique<DevToolsVideoConsumer>(base::BindRepeating(
&DevToolsVideoConsumerTest::OnFrameFromVideoConsumer,
base::Unretained(this)));
consumer_->SetFrameSinkId(
static_cast<content::WebContentsImpl*>(shell()->web_contents())
->GetRenderViewHost()
->GetWidget()
->GetFrameSinkId());
}
scoped_refptr<media::VideoFrame> GetFrame(int i) { return frames_[i]; }
size_t NumberOfFramesReceived() { return frames_.size(); }
void OnFrameFromVideoConsumer(scoped_refptr<media::VideoFrame> frame) {
run_loop_->Quit();
frames_.push_back(std::move(frame));
}
void WaitUntilFrameReceived() {
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
static gfx::Size GetVideoConsumerDefaultMinFrameSize() {
return DevToolsVideoConsumer::kDefaultMinFrameSize;
}
static gfx::Size GetVideoConsumerDefaultMaxFrameSize() {
return DevToolsVideoConsumer::kDefaultMaxFrameSize;
}
protected:
std::unique_ptr<DevToolsVideoConsumer> consumer_;
private:
std::vector<scoped_refptr<media::VideoFrame>> frames_;
std::unique_ptr<base::RunLoop> run_loop_;
};
// Tests that setting new frame dimensions via SetMinAndMaxFrameSizes
// produces frames of the new dimensions.
IN_PROC_BROWSER_TEST_F(DevToolsVideoConsumerTest,
DISABLED_SetMinAndMaxFramesChangesDimensions) {
ASSERT_TRUE(embedded_test_server()->Start());
// Complete navigation to a page and then start capture. Since navigation is
// complete before capturing, we only expect the refresh frame from the
// StartCapture call. Wait for this refresh frame and verify its info.
NavigateToURLBlockUntilNavigationsComplete(
shell(), embedded_test_server()->GetURL("/devtools/navigation.html"), 1);
consumer_->StartCapture();
WaitUntilFrameReceived();
size_t cur_frame_index = 0;
size_t num_frames_received = 1;
EXPECT_EQ(num_frames_received, NumberOfFramesReceived());
scoped_refptr<media::VideoFrame> frame = GetFrame(cur_frame_index);
EXPECT_EQ(frame->format(), kVideoCapturerDefaultPixelFormat);
EXPECT_TRUE(VerifyFrameSize(frame, GetVideoConsumerDefaultMinFrameSize(),
GetVideoConsumerDefaultMaxFrameSize()));
// Setting |kNewMinFrameSize| > |kDefaultMaxFrameSize| to disambiguate
// frames with older vs. newer dimensions.
const gfx::Size kNewMinFrameSize =
gfx::Size(GetVideoConsumerDefaultMaxFrameSize().width() + 1,
GetVideoConsumerDefaultMaxFrameSize().height() + 1);
// |kNewMaxFrameSize| only needs to be >= |kNewMinFrameSize|.
const gfx::Size kNewMaxFrameSize = gfx::Size(kNewMinFrameSize.width() + 500,
kNewMinFrameSize.height() + 500);
// Set the min and max frame sizes. This will call
// FrameSinkVideoCapturer::SetResolutionConstraints which triggers sending a
// refresh frame. Wait for this refresh frame and verify it's info.
consumer_->SetMinAndMaxFrameSize(kNewMinFrameSize, kNewMaxFrameSize);
WaitUntilFrameReceived();
EXPECT_EQ(++num_frames_received, NumberOfFramesReceived());
frame = GetFrame(++cur_frame_index);
EXPECT_EQ(frame->format(), kVideoCapturerDefaultPixelFormat);
EXPECT_TRUE(VerifyFrameSize(frame, kNewMinFrameSize, kNewMaxFrameSize));
// Stop capturing.
consumer_->StopCapture();
}
} // namespace content