123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- // Copyright 2016 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 "remoting/client/dual_buffer_frame_consumer.h"
- #include <memory>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
- #include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h"
- namespace remoting {
- namespace {
- webrtc::DesktopFrame* GetUnderlyingFrame(
- const std::unique_ptr<webrtc::DesktopFrame>& frame) {
- return reinterpret_cast<webrtc::SharedDesktopFrame*>(frame.get())->
- GetUnderlyingFrame();
- }
- void FillRGBARect(uint8_t r,
- uint8_t g,
- uint8_t b,
- uint8_t a,
- const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame) {
- for (int x = 0; x < rect.width(); x++) {
- for (int y = 0; y < rect.height(); y++) {
- uint8_t* data = frame->GetFrameDataAtPos(
- rect.top_left().add(webrtc::DesktopVector(x, y)));
- data[0] = r;
- data[1] = g;
- data[2] = b;
- data[3] = a;
- }
- }
- frame->mutable_updated_region()->SetRect(rect);
- }
- void CheckFrameColor(uint8_t r,
- uint8_t g,
- uint8_t b,
- uint8_t a,
- const webrtc::DesktopVector& pos,
- const webrtc::DesktopFrame& frame) {
- uint8_t* data = frame.GetFrameDataAtPos(pos);
- EXPECT_EQ(r, data[0]);
- EXPECT_EQ(g, data[1]);
- EXPECT_EQ(b, data[2]);
- EXPECT_EQ(a, data[3]);
- }
- } // namespace
- class DualBufferFrameConsumerTest : public testing::Test {
- public:
- void SetUp() override;
- protected:
- std::unique_ptr<DualBufferFrameConsumer> consumer_;
- std::unique_ptr<webrtc::DesktopFrame> received_frame_;
- base::OnceClosure done_closure_;
- private:
- void OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame,
- base::OnceClosure done);
- };
- void DualBufferFrameConsumerTest::SetUp() {
- consumer_ = std::make_unique<DualBufferFrameConsumer>(
- base::BindRepeating(&DualBufferFrameConsumerTest::OnFrameReceived,
- base::Unretained(this)),
- nullptr, protocol::FrameConsumer::FORMAT_RGBA);
- }
- void DualBufferFrameConsumerTest::OnFrameReceived(
- std::unique_ptr<webrtc::DesktopFrame> frame,
- base::OnceClosure done) {
- received_frame_ = std::move(frame);
- done_closure_ = std::move(done);
- }
- TEST_F(DualBufferFrameConsumerTest, AllocateOneFrame) {
- std::unique_ptr<webrtc::DesktopFrame> frame =
- consumer_->AllocateFrame(webrtc::DesktopSize(16, 16));
- ASSERT_TRUE(frame->size().equals(webrtc::DesktopSize(16, 16)));
- webrtc::DesktopFrame* raw_frame = frame.get();
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- EXPECT_EQ(raw_frame, received_frame_.get());
- }
- TEST_F(DualBufferFrameConsumerTest, BufferRotation) {
- webrtc::DesktopSize size16x16(16, 16);
- std::unique_ptr<webrtc::DesktopFrame> frame =
- consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- frame = consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame);
- EXPECT_NE(underlying_frame_1, underlying_frame_2);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- frame = consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame);
- EXPECT_EQ(underlying_frame_1, underlying_frame_3);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- frame = consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame);
- EXPECT_EQ(underlying_frame_2, underlying_frame_4);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- }
- TEST_F(DualBufferFrameConsumerTest, DrawAndMergeFrames) {
- webrtc::DesktopSize size2x2(2, 2);
- // X means uninitialized color.
- // Frame 1:
- // RR
- // RR
- std::unique_ptr<webrtc::DesktopFrame> frame =
- consumer_->AllocateFrame(size2x2);
- FillRGBARect(0xff, 0, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 2),
- frame.get());
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- // Frame 2:
- // GG
- // XX
- frame = consumer_->AllocateFrame(size2x2);
- FillRGBARect(0, 0xff, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 1),
- frame.get());
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- // Merged Frame:
- // GG
- // RR
- consumer_->RequestFullDesktopFrame();
- ASSERT_TRUE(received_frame_->size().equals(size2x2));
- CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(0, 0),
- *received_frame_);
- CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(0, 1),
- *received_frame_);
- CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0),
- *received_frame_);
- CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1),
- *received_frame_);
- // Frame 3:
- // BX
- // BX
- frame = consumer_->AllocateFrame(size2x2);
- FillRGBARect(0, 0, 0xff, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 1, 2),
- frame.get());
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- // Merged Frame:
- // BG
- // BR
- consumer_->RequestFullDesktopFrame();
- ASSERT_TRUE(received_frame_->size().equals(size2x2));
- CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 0),
- *received_frame_);
- CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 1),
- *received_frame_);
- CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0),
- *received_frame_);
- CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1),
- *received_frame_);
- }
- TEST_F(DualBufferFrameConsumerTest, ChangeScreenSizeAndReallocateBuffers) {
- webrtc::DesktopSize size16x16(16, 16);
- std::unique_ptr<webrtc::DesktopFrame> frame =
- consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- frame = consumer_->AllocateFrame(size16x16);
- webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame);
- EXPECT_NE(underlying_frame_1, underlying_frame_2);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- webrtc::DesktopSize size32x32(32, 32);
- frame = consumer_->AllocateFrame(size32x32);
- webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame);
- EXPECT_NE(underlying_frame_1, underlying_frame_3);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- frame = consumer_->AllocateFrame(size32x32);
- webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame);
- EXPECT_NE(underlying_frame_2, underlying_frame_4);
- consumer_->DrawFrame(std::move(frame), base::NullCallback());
- }
- } // namespace remoting
|