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
|
// 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
|