codec_test.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_frame.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/codec/codec_test.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/codec/video_decoder.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/codec/video_encoder.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using webrtc::DesktopRect; 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using webrtc::DesktopSize; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBytesPerPixel = 4; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some sample rects for testing. 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::vector<std::vector<DesktopRect> > MakeTestRectLists(DesktopSize size) { 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::vector<DesktopRect> > rect_lists; 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DesktopRect> rects; 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rects.push_back(DesktopRect::MakeXYWH(0, 0, size.width(), size.height())); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_lists.push_back(rects); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rects.clear(); 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rects.push_back(DesktopRect::MakeXYWH( 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 0, 0, size.width() / 2, size.height() / 2)); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_lists.push_back(rects); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rects.clear(); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rects.push_back(DesktopRect::MakeXYWH( 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size.width() / 2, size.height() / 2, 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size.width() / 2, size.height() / 2)); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_lists.push_back(rects); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rects.clear(); 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rects.push_back(DesktopRect::MakeXYWH(16, 16, 16, 16)); 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rects.push_back(DesktopRect::MakeXYWH(128, 64, 32, 32)); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_lists.push_back(rects); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rect_lists; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class to test the message output of the encoder. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoEncoderMessageTester { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderMessageTester() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : begin_rect_(0), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_data_(0), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_rect_(0), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) added_rects_(0), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(kWaitingForBeginRect), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strict_(false) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~VideoEncoderMessageTester() { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(begin_rect_, end_rect_); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(begin_rect_, 0); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kWaitingForBeginRect, state_); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strict_) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(added_rects_, begin_rect_); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we received the correct packet. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReceivedPacket(VideoPacket* packet) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == kWaitingForBeginRect) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kWaitingForRectData; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++begin_rect_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strict_) { 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DesktopRect rect = rects_.front(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rects_.pop_front(); 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(rect.left(), packet->format().x()); 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(rect.top(), packet->format().y()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rect.width(), packet->format().width()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rect.height(), packet->format().height()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == kWaitingForRectData) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (packet->has_data()) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++rect_data_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((packet->flags() & VideoPacket::LAST_PACKET) != 0) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expect that we have received some data. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(rect_data_, 0); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect_data_ = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kWaitingForBeginRect; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++end_rect_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((packet->flags() & VideoPacket::LAST_PARTITION) != 0) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LAST_PARTITION must always be marked with LAST_PACKET. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_strict(bool strict) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strict_ = strict; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddRects(const DesktopRect* rects, int count) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) added_rects_ += count; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWaitingForBeginRect, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWaitingForRectData, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int begin_rect_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rect_data_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int end_rect_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int added_rects_; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool strict_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::deque<DesktopRect> rects_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VideoEncoderMessageTester); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoDecoderTester { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) VideoDecoderTester(VideoDecoder* decoder, 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopSize& screen_size, 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopSize& view_size) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : screen_size_(screen_size), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_size_(view_size), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strict_(false), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_(decoder) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_data_.reset(new uint8[ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_size_.width() * view_size_.height() * kBytesPerPixel]); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(image_data_.get()); 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_->Initialize( 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkISize::Make(screen_size_.width(), screen_size_.height())); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset() { 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) expected_region_.Clear(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_region_.setEmpty(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetRenderedData() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(image_data_.get(), 0, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_size_.width() * view_size_.height() * kBytesPerPixel); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReceivedPacket(VideoPacket* packet) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoder::DecodeResult result = decoder_->DecodePacket(packet); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(VideoDecoder::DECODE_ERROR, result); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == VideoDecoder::DECODE_DONE) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderFrame(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RenderFrame() { 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_->RenderFrame( 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkISize::Make(view_size_.width(), view_size_.height()), 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkIRect::MakeWH(view_size_.width(), view_size_.height()), 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) image_data_.get(), 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) view_size_.width() * kBytesPerPixel, 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &update_region_); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReceivedPacket(packet.get()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_strict(bool strict) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strict_ = strict; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void set_frame(webrtc::DesktopFrame* frame) { 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame_ = frame; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddRects(const DesktopRect* rects, int count) { 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < count; ++i) { 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) expected_region_.AddRect(rects[i]); 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddRegion(const webrtc::DesktopRegion& region) { 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) expected_region_.AddRegion(region); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyResults() { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strict_) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(frame_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the content of the update region. 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(sergeyu): Change this to use DesktopRegion when it's capable of 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // merging the rectangles. 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkRegion expected_region; 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (webrtc::DesktopRegion::Iterator it(expected_region_); 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !it.IsAtEnd(); it.Advance()) { 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) expected_region.op( 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkIRect::MakeXYWH(it.rect().top(), it.rect().left(), 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it.rect().width(), it.rect().height()), 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkRegion::kUnion_Op); 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(expected_region, update_region_); 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int stride = view_size_.width() * kBytesPerPixel; 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(stride, frame_->stride()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int offset = stride * i.rect().top() + 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBytesPerPixel * i.rect().left(); 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const uint8* original = frame_->data() + offset; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* decoded = image_data_.get() + offset; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int row_size = kBytesPerPixel * i.rect().width(); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < i.rect().height(); ++y) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(original, decoded, row_size)) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Row " << y << " is different"; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original += stride; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded += stride; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The error at each pixel is the root mean square of the errors in 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the R, G, and B components, each normalized to [0, 1]. This routine 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // checks that the maximum and mean pixel errors do not exceed given limits. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyResultsApprox(const uint8* expected_view_data, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double max_error_limit, double mean_error_limit) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double max_error = 0.0; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double sum_error = 0.0; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_num = 0; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int stride = view_size_.width() * kBytesPerPixel; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int offset = stride * i.rect().top() + 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBytesPerPixel * i.rect().left(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* expected = expected_view_data + offset; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* actual = image_data_.get() + offset; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < i.rect().height(); ++y) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < i.rect().width(); ++x) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double error = CalculateError(expected, actual); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_error = std::max(max_error, error); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum_error += error; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++error_num; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected += 4; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual += 4; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LE(max_error, max_error_limit); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double mean_error = sum_error / error_num; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LE(mean_error, mean_error_limit); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Max error: " << max_error; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Mean error: " << mean_error; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double CalculateError(const uint8* original, const uint8* decoded) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double error_sum_squares = 0.0; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 3; i++) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double error = static_cast<double>(*original++) - 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<double>(*decoded++); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error /= 255.0; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_sum_squares += error * error; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original++; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded++; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sqrt(error_sum_squares / 3.0); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DesktopSize screen_size_; 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DesktopSize view_size_; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool strict_; 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopRegion expected_region_; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRegion update_region_; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoder* decoder_; 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<uint8[]> image_data_; 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopFrame* frame_; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The VideoEncoderTester provides a hook for retrieving the data, and passing 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the message to other subprograms for validaton. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoEncoderTester { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderTester(VideoEncoderMessageTester* message_tester) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : message_tester_(message_tester), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester_(NULL), 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_available_(0) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~VideoEncoderTester() { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(data_available_, 0); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DataAvailable(scoped_ptr<VideoPacket> packet) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++data_available_; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_tester_->ReceivedPacket(packet.get()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the message to the VideoDecoderTester. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_tester_) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester_->ReceivedPacket(packet.get()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddRects(const DesktopRect* rects, int count) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_tester_->AddRects(rects, count); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_decoder_tester(VideoDecoderTester* decoder_tester) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester_ = decoder_tester; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderMessageTester* message_tester_; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoderTester* decoder_tester_; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_available_; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<webrtc::DesktopFrame> PrepareFrame(const DesktopSize& size) { 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size)); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srand(0); 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int memory_size = size.width() * size.height() * kBytesPerPixel; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < memory_size; ++i) { 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->data()[i] = rand() % 256; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return frame.Pass(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestEncodingRects(VideoEncoder* encoder, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderTester* tester, 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopFrame* frame, 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopRect* rects, 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int count) { 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->mutable_updated_region()->Clear(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < count; ++i) { 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->mutable_updated_region()->AddRect(rects[i]); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester->AddRects(rects, count); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) encoder->Encode(frame, base::Bind( 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &VideoEncoderTester::DataAvailable, base::Unretained(tester))); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVideoEncoder(VideoEncoder* encoder, bool strict) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSizes[] = {320, 319, 317, 150}; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderMessageTester message_tester; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_tester.set_strict(strict); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderTester tester(&message_tester); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DesktopSize size = DesktopSize(kSizes[xi], kSizes[yi]); 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(size); 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::vector<DesktopRect> > test_rect_lists = 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTestRectLists(size); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < test_rect_lists.size(); ++i) { 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<DesktopRect>& test_rects = test_rect_lists[i]; 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestEncodingRects(encoder, &tester, frame.get(), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &test_rects[0], test_rects.size()); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestEncodeDecodeRects(VideoEncoder* encoder, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderTester* encoder_tester, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoderTester* decoder_tester, 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopFrame* frame, 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopRect* rects, int count) { 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->mutable_updated_region()->Clear(); 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < count; ++i) { 39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->mutable_updated_region()->AddRect(rects[i]); 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoder_tester->AddRects(rects, count); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester->AddRects(rects, count); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate random data for the updated region. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srand(0); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < count; ++i) { 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int row_size = 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopFrame::kBytesPerPixel * rects[i].width(); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint8* memory = frame->data() + 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->stride() * rects[i].top() + 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopFrame::kBytesPerPixel * rects[i].left(); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < rects[i].height(); ++y) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < row_size; ++x) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory[x] = rand() % 256; 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memory += frame->stride(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) encoder->Encode(frame, base::Bind(&VideoEncoderTester::DataAvailable, 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(encoder_tester))); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester->VerifyResults(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester->Reset(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVideoEncoderDecoder( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DesktopSize kSize = DesktopSize(320, 240); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderMessageTester message_tester; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_tester.set_strict(strict); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoEncoderTester encoder_tester(&message_tester); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(kSize); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoderTester decoder_tester(decoder, kSize, kSize); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester.set_strict(strict); 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_tester.set_frame(frame.get()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoder_tester.set_decoder_tester(&decoder_tester); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::vector<DesktopRect> > test_rect_lists = 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MakeTestRectLists(kSize); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < test_rect_lists.size(); ++i) { 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<DesktopRect> test_rects = test_rect_lists[i]; 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame.get(), &test_rects[0], test_rects.size()); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void FillWithGradient(webrtc::DesktopFrame* frame) { 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int j = 0; j < frame->size().height(); ++j) { 45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint8* p = frame->data() + j * frame->stride(); 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < frame->size().width(); ++i) { 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *p++ = (255.0 * i) / frame->size().width(); 45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *p++ = (164.0 * j) / frame->size().height(); 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *p++ = (82.0 * (i + j)) / 45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (frame->size().width() + frame->size().height()); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p++ = 0; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoder* decoder, 46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopSize& screen_size, 46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DesktopSize& view_size, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double max_error_limit, 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double mean_error_limit) { 46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<webrtc::BasicDesktopFrame> frame( 46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new webrtc::BasicDesktopFrame(screen_size)); 47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FillWithGradient(frame.get()); 47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(screen_size)); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<webrtc::BasicDesktopFrame> expected_result( 47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new webrtc::BasicDesktopFrame(view_size)); 47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FillWithGradient(expected_result.get()); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoDecoderTester decoder_tester(decoder, screen_size, view_size); 47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_tester.set_frame(frame.get()); 47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_tester.AddRegion(frame->updated_region()); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) encoder->Encode(frame.get(), 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&VideoDecoderTester::ReceivedScopedPacket, 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&decoder_tester))); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_tester.VerifyResultsApprox(expected_result->data(), 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_error_limit, mean_error_limit); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the decoder correctly re-renders the frame if its client 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidates the frame. 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester.ResetRenderedData(); 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder->Invalidate( 49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkISize::Make(view_size.width(), view_size.height()), 49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkRegion(SkIRect::MakeWH(view_size.width(), view_size.height()))); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_tester.RenderFrame(); 49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoder_tester.VerifyResultsApprox(expected_result->data(), 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_error_limit, mean_error_limit); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 500