blob: 6754a081318e0c125a5c007da3e09de82a504d09 [file] [log] [blame]
[email protected]dc454a7c2011-08-12 22:01:131// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]fb13c762010-07-24 02:22:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]542bdfe2010-11-30 03:55:475#include <deque>
[email protected]fb13c762010-07-24 02:22:076#include <stdlib.h>
7
[email protected]dc454a7c2011-08-12 22:01:138#include "base/memory/scoped_ptr.h"
[email protected]fb13c762010-07-24 02:22:079#include "media/base/video_frame.h"
[email protected]28dc4212011-02-08 20:44:0010#include "remoting/base/base_mock_objects.h"
[email protected]fb13c762010-07-24 02:22:0711#include "remoting/base/codec_test.h"
[email protected]8ea7a1672010-10-04 19:48:4212#include "remoting/base/decoder.h"
[email protected]fb13c762010-07-24 02:22:0713#include "remoting/base/encoder.h"
[email protected]c3af26f332010-10-06 22:46:0014#include "remoting/base/util.h"
[email protected]fb13c762010-07-24 02:22:0715#include "testing/gtest/include/gtest/gtest.h"
16
17static const int kWidth = 320;
18static const int kHeight = 240;
19static const int kBytesPerPixel = 4;
20
21// Some sample rects for testing.
[email protected]dc454a7c2011-08-12 22:01:1322static const SkIRect kTestRects[] = {
23 SkIRect::MakeXYWH(0, 0, kWidth, kHeight),
24 SkIRect::MakeXYWH(0, 0, kWidth / 2, kHeight / 2),
25 SkIRect::MakeXYWH(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
26 SkIRect::MakeXYWH(16, 16, 16, 16),
27 SkIRect::MakeXYWH(128, 64, 32, 32),
[email protected]fb13c762010-07-24 02:22:0728};
29
30namespace remoting {
31
[email protected]fb13c762010-07-24 02:22:0732// A class to test the message output of the encoder.
33class EncoderMessageTester {
34 public:
35 EncoderMessageTester()
36 : begin_rect_(0),
37 rect_data_(0),
38 end_rect_(0),
[email protected]66db1af92010-07-27 01:42:4639 added_rects_(0),
[email protected]fb13c762010-07-24 02:22:0740 state_(kWaitingForBeginRect),
41 strict_(false) {
42 }
43
44 ~EncoderMessageTester() {
45 EXPECT_EQ(begin_rect_, end_rect_);
[email protected]df10bf12010-09-28 22:19:4846 EXPECT_GT(begin_rect_, 0);
[email protected]fb13c762010-07-24 02:22:0747 EXPECT_EQ(kWaitingForBeginRect, state_);
[email protected]df10bf12010-09-28 22:19:4848 if (strict_) {
49 EXPECT_EQ(added_rects_, begin_rect_);
[email protected]66db1af92010-07-27 01:42:4650 }
[email protected]fb13c762010-07-24 02:22:0751 }
52
[email protected]137e58f12010-12-07 19:35:4353 // Test that we received the correct packet.
54 void ReceivedPacket(VideoPacket* packet) {
[email protected]fb13c762010-07-24 02:22:0755 if (state_ == kWaitingForBeginRect) {
[email protected]137e58f12010-12-07 19:35:4356 EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0);
[email protected]fb13c762010-07-24 02:22:0757 state_ = kWaitingForRectData;
58 ++begin_rect_;
59
60 if (strict_) {
[email protected]dc454a7c2011-08-12 22:01:1361 SkIRect rect = rects_.front();
[email protected]fb13c762010-07-24 02:22:0762 rects_.pop_front();
[email protected]dc454a7c2011-08-12 22:01:1363 EXPECT_EQ(rect.fLeft, packet->format().x());
64 EXPECT_EQ(rect.fTop, packet->format().y());
[email protected]137e58f12010-12-07 19:35:4365 EXPECT_EQ(rect.width(), packet->format().width());
66 EXPECT_EQ(rect.height(), packet->format().height());
[email protected]fb13c762010-07-24 02:22:0767 }
68 } else {
[email protected]137e58f12010-12-07 19:35:4369 EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0);
[email protected]fb13c762010-07-24 02:22:0770 }
71
72 if (state_ == kWaitingForRectData) {
[email protected]137e58f12010-12-07 19:35:4373 if (packet->has_data()) {
[email protected]fb13c762010-07-24 02:22:0774 ++rect_data_;
75 }
76
[email protected]137e58f12010-12-07 19:35:4377 if ((packet->flags() & VideoPacket::LAST_PACKET) != 0) {
[email protected]fb13c762010-07-24 02:22:0778 // Expect that we have received some data.
79 EXPECT_GT(rect_data_, 0);
80 rect_data_ = 0;
81 state_ = kWaitingForBeginRect;
82 ++end_rect_;
83 }
[email protected]5bc71832010-12-09 01:34:0884
85 if ((packet->flags() & VideoPacket::LAST_PARTITION) != 0) {
86 // LAST_PARTITION must always be marked with LAST_PACKET.
87 EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0);
88 }
[email protected]fb13c762010-07-24 02:22:0789 }
90 }
91
92 void set_strict(bool strict) {
93 strict_ = strict;
94 }
95
[email protected]dc454a7c2011-08-12 22:01:1396 void AddRects(const SkIRect* rects, int count) {
[email protected]fb13c762010-07-24 02:22:0797 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count);
[email protected]66db1af92010-07-27 01:42:4698 added_rects_ += count;
[email protected]fb13c762010-07-24 02:22:0799 }
100
101 private:
102 enum State {
103 kWaitingForBeginRect,
104 kWaitingForRectData,
105 };
106
107 int begin_rect_;
108 int rect_data_;
109 int end_rect_;
[email protected]66db1af92010-07-27 01:42:46110 int added_rects_;
[email protected]fb13c762010-07-24 02:22:07111 State state_;
112 bool strict_;
113
[email protected]dc454a7c2011-08-12 22:01:13114 std::deque<SkIRect> rects_;
[email protected]fb13c762010-07-24 02:22:07115
116 DISALLOW_COPY_AND_ASSIGN(EncoderMessageTester);
117};
118
119class DecoderTester {
120 public:
[email protected]542bdfe2010-11-30 03:55:47121 DecoderTester(Decoder* decoder)
[email protected]fb13c762010-07-24 02:22:07122 : strict_(false),
[email protected]137e58f12010-12-07 19:35:43123 decoder_(decoder) {
[email protected]54370ef2011-07-18 22:53:05124 frame_ = media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
125 kWidth, kHeight,
126 base::TimeDelta(),
127 base::TimeDelta());
[email protected]fb13c762010-07-24 02:22:07128 EXPECT_TRUE(frame_.get());
[email protected]137e58f12010-12-07 19:35:43129 decoder_->Initialize(frame_);
[email protected]fb13c762010-07-24 02:22:07130 }
131
[email protected]137e58f12010-12-07 19:35:43132 void Reset() {
133 rects_.clear();
134 update_rects_.clear();
135 }
[email protected]cee5dba2010-12-07 03:19:48136
[email protected]137e58f12010-12-07 19:35:43137 void ReceivedPacket(VideoPacket* packet) {
138 Decoder::DecodeResult result = decoder_->DecodePacket(packet);
[email protected]cee5dba2010-12-07 03:19:48139
[email protected]137e58f12010-12-07 19:35:43140 ASSERT_NE(Decoder::DECODE_ERROR, result);
141
142 if (result == Decoder::DECODE_DONE) {
143 decoder_->GetUpdatedRects(&update_rects_);
[email protected]cee5dba2010-12-07 03:19:48144 }
[email protected]fb13c762010-07-24 02:22:07145 }
146
147 void set_strict(bool strict) {
148 strict_ = strict;
149 }
150
151 void set_capture_data(scoped_refptr<CaptureData> data) {
152 capture_data_ = data;
153 }
154
[email protected]dc454a7c2011-08-12 22:01:13155 void AddRects(const SkIRect* rects, int count) {
[email protected]fb13c762010-07-24 02:22:07156 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count);
157 }
158
[email protected]137e58f12010-12-07 19:35:43159 void VerifyResults() {
[email protected]fb13c762010-07-24 02:22:07160 if (!strict_)
161 return;
[email protected]66db1af92010-07-27 01:42:46162
[email protected]137e58f12010-12-07 19:35:43163 ASSERT_TRUE(capture_data_.get());
164
[email protected]66db1af92010-07-27 01:42:46165 // Test the content of the update rect.
[email protected]137e58f12010-12-07 19:35:43166 ASSERT_EQ(rects_.size(), update_rects_.size());
[email protected]fb13c762010-07-24 02:22:07167 for (size_t i = 0; i < update_rects_.size(); ++i) {
[email protected]bcad2682011-09-30 20:35:26168 EXPECT_EQ(rects_[i], update_rects_[i]);
[email protected]66db1af92010-07-27 01:42:46169
170 EXPECT_EQ(frame_->stride(0), capture_data_->data_planes().strides[0]);
171 const int stride = frame_->stride(0);
[email protected]bcad2682011-09-30 20:35:26172 const int offset = stride * update_rects_[i].fTop +
173 kBytesPerPixel * update_rects_[i].fLeft;
[email protected]66db1af92010-07-27 01:42:46174 const uint8* original = capture_data_->data_planes().data[0] + offset;
175 const uint8* decoded = frame_->data(0) + offset;
176 const int row_size = kBytesPerPixel * update_rects_[i].width();
177 for (int y = 0; y < update_rects_[i].height(); ++y) {
178 EXPECT_EQ(0, memcmp(original, decoded, row_size))
179 << "Row " << y << " is different";
180 original += stride;
181 decoded += stride;
182 }
[email protected]fb13c762010-07-24 02:22:07183 }
184 }
185
[email protected]137e58f12010-12-07 19:35:43186 private:
[email protected]fb13c762010-07-24 02:22:07187 bool strict_;
[email protected]dc454a7c2011-08-12 22:01:13188 std::deque<SkIRect> rects_;
[email protected]bcad2682011-09-30 20:35:26189 RectVector update_rects_;
[email protected]fb13c762010-07-24 02:22:07190 Decoder* decoder_;
191 scoped_refptr<media::VideoFrame> frame_;
192 scoped_refptr<CaptureData> capture_data_;
[email protected]fb13c762010-07-24 02:22:07193
194 DISALLOW_COPY_AND_ASSIGN(DecoderTester);
195};
196
[email protected]8ea7a1672010-10-04 19:48:42197// The EncoderTester provides a hook for retrieving the data, and passing the
198// message to other subprograms for validaton.
[email protected]fb13c762010-07-24 02:22:07199class EncoderTester {
200 public:
[email protected]137e58f12010-12-07 19:35:43201 EncoderTester(EncoderMessageTester* message_tester)
[email protected]fb13c762010-07-24 02:22:07202 : message_tester_(message_tester),
[email protected]fb13c762010-07-24 02:22:07203 decoder_tester_(NULL),
204 data_available_(0) {
205 }
206
207 ~EncoderTester() {
208 EXPECT_GT(data_available_, 0);
209 }
210
[email protected]137e58f12010-12-07 19:35:43211 void DataAvailable(VideoPacket *packet) {
[email protected]fb13c762010-07-24 02:22:07212 ++data_available_;
[email protected]137e58f12010-12-07 19:35:43213 message_tester_->ReceivedPacket(packet);
[email protected]fb13c762010-07-24 02:22:07214
215 // Send the message to the DecoderTester.
216 if (decoder_tester_) {
[email protected]137e58f12010-12-07 19:35:43217 decoder_tester_->ReceivedPacket(packet);
[email protected]cee5dba2010-12-07 03:19:48218 }
[email protected]137e58f12010-12-07 19:35:43219
220 delete packet;
[email protected]fb13c762010-07-24 02:22:07221 }
222
[email protected]dc454a7c2011-08-12 22:01:13223 void AddRects(const SkIRect* rects, int count) {
[email protected]fb13c762010-07-24 02:22:07224 message_tester_->AddRects(rects, count);
225 }
226
227 void set_decoder_tester(DecoderTester* decoder_tester) {
228 decoder_tester_ = decoder_tester;
229 }
230
231 private:
232 EncoderMessageTester* message_tester_;
[email protected]fb13c762010-07-24 02:22:07233 DecoderTester* decoder_tester_;
234 int data_available_;
235
236 DISALLOW_COPY_AND_ASSIGN(EncoderTester);
237};
238
[email protected]137e58f12010-12-07 19:35:43239scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format,
[email protected]fb13c762010-07-24 02:22:07240 uint8** memory) {
241 // TODO(hclam): Support also YUV format.
[email protected]137e58f12010-12-07 19:35:43242 CHECK_EQ(format, media::VideoFrame::RGB32);
[email protected]fb13c762010-07-24 02:22:07243 int size = kWidth * kHeight * kBytesPerPixel;
244
245 *memory = new uint8[size];
246 srand(0);
247 for (int i = 0; i < size; ++i) {
248 (*memory)[i] = rand() % 256;
249 }
250
251 DataPlanes planes;
252 memset(planes.data, 0, sizeof(planes.data));
253 memset(planes.strides, 0, sizeof(planes.strides));
254 planes.data[0] = *memory;
255 planes.strides[0] = kWidth * kBytesPerPixel;
256
257 scoped_refptr<CaptureData> data =
[email protected]bcad2682011-09-30 20:35:26258 new CaptureData(planes, SkISize::Make(kWidth, kHeight), format);
[email protected]fb13c762010-07-24 02:22:07259 return data;
260}
261
262static void TestEncodingRects(Encoder* encoder,
263 EncoderTester* tester,
264 scoped_refptr<CaptureData> data,
[email protected]dc454a7c2011-08-12 22:01:13265 const SkIRect* rects, int count) {
266 data->mutable_dirty_region().setEmpty();
[email protected]88552a92010-08-06 22:50:00267 for (int i = 0; i < count; ++i) {
[email protected]dc454a7c2011-08-12 22:01:13268 data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op);
[email protected]88552a92010-08-06 22:50:00269 }
[email protected]fb13c762010-07-24 02:22:07270 tester->AddRects(rects, count);
271
272 encoder->Encode(data, true,
273 NewCallback(tester, &EncoderTester::DataAvailable));
274}
275
276void TestEncoder(Encoder* encoder, bool strict) {
277 EncoderMessageTester message_tester;
278 message_tester.set_strict(strict);
279
[email protected]137e58f12010-12-07 19:35:43280 EncoderTester tester(&message_tester);
[email protected]fb13c762010-07-24 02:22:07281
282 uint8* memory;
283 scoped_refptr<CaptureData> data =
[email protected]137e58f12010-12-07 19:35:43284 PrepareEncodeData(media::VideoFrame::RGB32, &memory);
[email protected]dc454a7c2011-08-12 22:01:13285 scoped_array<uint8> memory_wrapper(memory);
[email protected]fb13c762010-07-24 02:22:07286
287 TestEncodingRects(encoder, &tester, data, kTestRects, 1);
288 TestEncodingRects(encoder, &tester, data, kTestRects + 1, 1);
289 TestEncodingRects(encoder, &tester, data, kTestRects + 2, 1);
290 TestEncodingRects(encoder, &tester, data, kTestRects + 3, 2);
[email protected]fb13c762010-07-24 02:22:07291}
292
293static void TestEncodingRects(Encoder* encoder,
294 EncoderTester* encoder_tester,
295 DecoderTester* decoder_tester,
296 scoped_refptr<CaptureData> data,
[email protected]dc454a7c2011-08-12 22:01:13297 const SkIRect* rects, int count) {
298 data->mutable_dirty_region().setEmpty();
[email protected]88552a92010-08-06 22:50:00299 for (int i = 0; i < count; ++i) {
[email protected]dc454a7c2011-08-12 22:01:13300 data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op);
[email protected]88552a92010-08-06 22:50:00301 }
[email protected]fb13c762010-07-24 02:22:07302 encoder_tester->AddRects(rects, count);
303 decoder_tester->AddRects(rects, count);
[email protected]fb13c762010-07-24 02:22:07304
[email protected]66db1af92010-07-27 01:42:46305 // Generate random data for the updated rects.
306 srand(0);
307 for (int i = 0; i < count; ++i) {
[email protected]dc454a7c2011-08-12 22:01:13308 const SkIRect& rect = rects[i];
[email protected]66db1af92010-07-27 01:42:46309 const int bytes_per_pixel = GetBytesPerPixel(data->pixel_format());
310 const int row_size = bytes_per_pixel * rect.width();
311 uint8* memory = data->data_planes().data[0] +
[email protected]dc454a7c2011-08-12 22:01:13312 data->data_planes().strides[0] * rect.fTop +
313 bytes_per_pixel * rect.fLeft;
[email protected]66db1af92010-07-27 01:42:46314 for (int y = 0; y < rect.height(); ++y) {
315 for (int x = 0; x < row_size; ++x)
316 memory[x] = rand() % 256;
317 memory += data->data_planes().strides[0];
318 }
319 }
320
[email protected]fb13c762010-07-24 02:22:07321 encoder->Encode(data, true,
322 NewCallback(encoder_tester, &EncoderTester::DataAvailable));
[email protected]137e58f12010-12-07 19:35:43323 decoder_tester->VerifyResults();
324 decoder_tester->Reset();
[email protected]fb13c762010-07-24 02:22:07325}
326
327void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) {
328 EncoderMessageTester message_tester;
329 message_tester.set_strict(strict);
330
[email protected]137e58f12010-12-07 19:35:43331 EncoderTester encoder_tester(&message_tester);
[email protected]fb13c762010-07-24 02:22:07332
333 uint8* memory;
334 scoped_refptr<CaptureData> data =
[email protected]137e58f12010-12-07 19:35:43335 PrepareEncodeData(media::VideoFrame::RGB32, &memory);
[email protected]dc454a7c2011-08-12 22:01:13336 scoped_array<uint8> memory_wrapper(memory);
337
[email protected]fb13c762010-07-24 02:22:07338 DecoderTester decoder_tester(decoder);
339 decoder_tester.set_strict(strict);
340 decoder_tester.set_capture_data(data);
341 encoder_tester.set_decoder_tester(&decoder_tester);
342
343 TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data,
344 kTestRects, 1);
345 TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data,
346 kTestRects + 1, 1);
347 TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data,
348 kTestRects + 2, 1);
349 TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data,
350 kTestRects + 3, 2);
[email protected]fb13c762010-07-24 02:22:07351}
352
353} // namespace remoting
354
355DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::DecoderTester);