OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
12 #include "remoting/codec/codec_test.h" | 12 #include "remoting/codec/codec_test.h" |
13 #include "remoting/codec/video_decoder.h" | 13 #include "remoting/codec/video_decoder.h" |
14 #include "remoting/codec/video_encoder.h" | 14 #include "remoting/codec/video_encoder.h" |
15 #include "remoting/base/util.h" | 15 #include "remoting/base/util.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
18 | 18 |
| 19 using webrtc::BasicDesktopFrame; |
| 20 using webrtc::DesktopFrame; |
19 using webrtc::DesktopRect; | 21 using webrtc::DesktopRect; |
20 using webrtc::DesktopRegion; | 22 using webrtc::DesktopRegion; |
21 using webrtc::DesktopSize; | 23 using webrtc::DesktopSize; |
22 | 24 |
23 namespace { | 25 namespace { |
24 | 26 |
25 const int kBytesPerPixel = 4; | 27 const int kBytesPerPixel = 4; |
26 | 28 |
27 // Some sample rects for testing. | 29 // Some sample rects for testing. |
28 std::vector<std::vector<DesktopRect> > MakeTestRectLists(DesktopSize size) { | 30 std::vector<std::vector<DesktopRect> > MakeTestRectLists(DesktopSize size) { |
(...skipping 28 matching lines...) Expand all Loading... |
57 const DesktopSize& view_size) | 59 const DesktopSize& view_size) |
58 : screen_size_(screen_size), | 60 : screen_size_(screen_size), |
59 view_size_(view_size), | 61 view_size_(view_size), |
60 strict_(false), | 62 strict_(false), |
61 decoder_(decoder), | 63 decoder_(decoder), |
62 frame_(NULL) { | 64 frame_(NULL) { |
63 image_data_.reset(new uint8[ | 65 image_data_.reset(new uint8[ |
64 view_size_.width() * view_size_.height() * kBytesPerPixel]); | 66 view_size_.width() * view_size_.height() * kBytesPerPixel]); |
65 EXPECT_TRUE(image_data_.get()); | 67 EXPECT_TRUE(image_data_.get()); |
66 decoder_->Initialize( | 68 decoder_->Initialize( |
67 webrtc::DesktopSize(screen_size_.width(), screen_size_.height())); | 69 DesktopSize(screen_size_.width(), screen_size_.height())); |
68 } | 70 } |
69 | 71 |
70 void Reset() { | 72 void Reset() { |
71 expected_region_.Clear(); | 73 expected_region_.Clear(); |
72 update_region_.Clear(); | 74 update_region_.Clear(); |
73 } | 75 } |
74 | 76 |
75 void ResetRenderedData() { | 77 void ResetRenderedData() { |
76 memset(image_data_.get(), 0, | 78 memset(image_data_.get(), 0, |
77 view_size_.width() * view_size_.height() * kBytesPerPixel); | 79 view_size_.width() * view_size_.height() * kBytesPerPixel); |
78 } | 80 } |
79 | 81 |
80 void ReceivedPacket(VideoPacket* packet) { | 82 void ReceivedPacket(VideoPacket* packet) { |
81 ASSERT_TRUE(decoder_->DecodePacket(*packet)); | 83 ASSERT_TRUE(decoder_->DecodePacket(*packet)); |
82 | 84 |
83 RenderFrame(); | 85 RenderFrame(); |
84 } | 86 } |
85 | 87 |
86 void RenderFrame() { | 88 void RenderFrame() { |
87 decoder_->RenderFrame( | 89 decoder_->RenderFrame( |
88 webrtc::DesktopSize(view_size_.width(), view_size_.height()), | 90 DesktopSize(view_size_.width(), view_size_.height()), |
89 webrtc::DesktopRect::MakeWH(view_size_.width(), view_size_.height()), | 91 DesktopRect::MakeWH(view_size_.width(), view_size_.height()), |
90 image_data_.get(), view_size_.width() * kBytesPerPixel, | 92 image_data_.get(), view_size_.width() * kBytesPerPixel, |
91 &update_region_); | 93 &update_region_); |
92 } | 94 } |
93 | 95 |
94 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { | 96 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
95 ReceivedPacket(packet.get()); | 97 ReceivedPacket(packet.get()); |
96 } | 98 } |
97 | 99 |
98 void set_strict(bool strict) { | 100 void set_strict(bool strict) { |
99 strict_ = strict; | 101 strict_ = strict; |
100 } | 102 } |
101 | 103 |
102 void set_frame(webrtc::DesktopFrame* frame) { | 104 void set_frame(DesktopFrame* frame) { |
103 frame_ = frame; | 105 frame_ = frame; |
104 } | 106 } |
105 | 107 |
106 void AddRects(const DesktopRect* rects, int count) { | 108 void AddRects(const DesktopRect* rects, int count) { |
107 for (int i = 0; i < count; ++i) { | 109 for (int i = 0; i < count; ++i) { |
108 expected_region_.AddRect(rects[i]); | 110 expected_region_.AddRect(rects[i]); |
109 } | 111 } |
110 } | 112 } |
111 | 113 |
112 void AddRegion(const webrtc::DesktopRegion& region) { | 114 void AddRegion(const DesktopRegion& region) { |
113 expected_region_.AddRegion(region); | 115 expected_region_.AddRegion(region); |
114 } | 116 } |
115 | 117 |
116 void VerifyResults() { | 118 void VerifyResults() { |
117 if (!strict_) | 119 if (!strict_) |
118 return; | 120 return; |
119 | 121 |
120 ASSERT_TRUE(frame_); | 122 ASSERT_TRUE(frame_); |
121 | 123 |
122 // Test the content of the update region. | 124 // Test the content of the update region. |
123 EXPECT_TRUE(expected_region_.Equals(update_region_)); | 125 EXPECT_TRUE(expected_region_.Equals(update_region_)); |
124 | 126 |
125 for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd(); | 127 for (DesktopRegion::Iterator i(update_region_); !i.IsAtEnd(); |
126 i.Advance()) { | 128 i.Advance()) { |
127 const int stride = view_size_.width() * kBytesPerPixel; | 129 const int stride = view_size_.width() * kBytesPerPixel; |
128 EXPECT_EQ(stride, frame_->stride()); | 130 EXPECT_EQ(stride, frame_->stride()); |
129 const int offset = stride * i.rect().top() + | 131 const int offset = stride * i.rect().top() + |
130 kBytesPerPixel * i.rect().left(); | 132 kBytesPerPixel * i.rect().left(); |
131 const uint8* original = frame_->data() + offset; | 133 const uint8* original = frame_->data() + offset; |
132 const uint8* decoded = image_data_.get() + offset; | 134 const uint8* decoded = image_data_.get() + offset; |
133 const int row_size = kBytesPerPixel * i.rect().width(); | 135 const int row_size = kBytesPerPixel * i.rect().width(); |
134 for (int y = 0; y < i.rect().height(); ++y) { | 136 for (int y = 0; y < i.rect().height(); ++y) { |
135 EXPECT_EQ(0, memcmp(original, decoded, row_size)) | 137 EXPECT_EQ(0, memcmp(original, decoded, row_size)) |
136 << "Row " << y << " is different"; | 138 << "Row " << y << " is different"; |
137 original += stride; | 139 original += stride; |
138 decoded += stride; | 140 decoded += stride; |
139 } | 141 } |
140 } | 142 } |
141 } | 143 } |
142 | 144 |
143 // The error at each pixel is the root mean square of the errors in | 145 // The error at each pixel is the root mean square of the errors in |
144 // the R, G, and B components, each normalized to [0, 1]. This routine | 146 // the R, G, and B components, each normalized to [0, 1]. This routine |
145 // checks that the maximum and mean pixel errors do not exceed given limits. | 147 // checks that the maximum and mean pixel errors do not exceed given limits. |
146 void VerifyResultsApprox(const uint8* expected_view_data, | 148 void VerifyResultsApprox(const uint8* expected_view_data, |
147 double max_error_limit, double mean_error_limit) { | 149 double max_error_limit, double mean_error_limit) { |
148 double max_error = 0.0; | 150 double max_error = 0.0; |
149 double sum_error = 0.0; | 151 double sum_error = 0.0; |
150 int error_num = 0; | 152 int error_num = 0; |
151 for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd(); | 153 for (DesktopRegion::Iterator i(update_region_); !i.IsAtEnd(); |
152 i.Advance()) { | 154 i.Advance()) { |
153 const int stride = view_size_.width() * kBytesPerPixel; | 155 const int stride = view_size_.width() * kBytesPerPixel; |
154 const int offset = stride * i.rect().top() + | 156 const int offset = stride * i.rect().top() + |
155 kBytesPerPixel * i.rect().left(); | 157 kBytesPerPixel * i.rect().left(); |
156 const uint8* expected = expected_view_data + offset; | 158 const uint8* expected = expected_view_data + offset; |
157 const uint8* actual = image_data_.get() + offset; | 159 const uint8* actual = image_data_.get() + offset; |
158 for (int y = 0; y < i.rect().height(); ++y) { | 160 for (int y = 0; y < i.rect().height(); ++y) { |
159 for (int x = 0; x < i.rect().width(); ++x) { | 161 for (int x = 0; x < i.rect().width(); ++x) { |
160 double error = CalculateError(expected, actual); | 162 double error = CalculateError(expected, actual); |
161 max_error = std::max(max_error, error); | 163 max_error = std::max(max_error, error); |
(...skipping 21 matching lines...) Expand all Loading... |
183 } | 185 } |
184 original++; | 186 original++; |
185 decoded++; | 187 decoded++; |
186 return sqrt(error_sum_squares / 3.0); | 188 return sqrt(error_sum_squares / 3.0); |
187 } | 189 } |
188 | 190 |
189 private: | 191 private: |
190 DesktopSize screen_size_; | 192 DesktopSize screen_size_; |
191 DesktopSize view_size_; | 193 DesktopSize view_size_; |
192 bool strict_; | 194 bool strict_; |
193 webrtc::DesktopRegion expected_region_; | 195 DesktopRegion expected_region_; |
194 webrtc::DesktopRegion update_region_; | 196 DesktopRegion update_region_; |
195 VideoDecoder* decoder_; | 197 VideoDecoder* decoder_; |
196 scoped_ptr<uint8[]> image_data_; | 198 scoped_ptr<uint8[]> image_data_; |
197 webrtc::DesktopFrame* frame_; | 199 DesktopFrame* frame_; |
198 | 200 |
199 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); | 201 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); |
200 }; | 202 }; |
201 | 203 |
202 // The VideoEncoderTester provides a hook for retrieving the data, and passing | 204 // The VideoEncoderTester provides a hook for retrieving the data, and passing |
203 // the message to other subprograms for validaton. | 205 // the message to other subprograms for validaton. |
204 class VideoEncoderTester { | 206 class VideoEncoderTester { |
205 public: | 207 public: |
206 VideoEncoderTester() | 208 VideoEncoderTester() |
207 : decoder_tester_(NULL), | 209 : decoder_tester_(NULL), |
(...skipping 16 matching lines...) Expand all Loading... |
224 decoder_tester_ = decoder_tester; | 226 decoder_tester_ = decoder_tester; |
225 } | 227 } |
226 | 228 |
227 private: | 229 private: |
228 VideoDecoderTester* decoder_tester_; | 230 VideoDecoderTester* decoder_tester_; |
229 int data_available_; | 231 int data_available_; |
230 | 232 |
231 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); | 233 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); |
232 }; | 234 }; |
233 | 235 |
234 scoped_ptr<webrtc::DesktopFrame> PrepareFrame(const DesktopSize& size) { | 236 scoped_ptr<DesktopFrame> PrepareFrame(const DesktopSize& size) { |
235 scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size)); | 237 scoped_ptr<DesktopFrame> frame(new BasicDesktopFrame(size)); |
236 | 238 |
237 srand(0); | 239 srand(0); |
238 int memory_size = size.width() * size.height() * kBytesPerPixel; | 240 int memory_size = size.width() * size.height() * kBytesPerPixel; |
239 for (int i = 0; i < memory_size; ++i) { | 241 for (int i = 0; i < memory_size; ++i) { |
240 frame->data()[i] = rand() % 256; | 242 frame->data()[i] = rand() % 256; |
241 } | 243 } |
242 | 244 |
243 return frame.Pass(); | 245 return frame.Pass(); |
244 } | 246 } |
245 | 247 |
(...skipping 27 matching lines...) Expand all Loading... |
273 TestEncodingRects(encoder, &tester, frame.get(), | 275 TestEncodingRects(encoder, &tester, frame.get(), |
274 &test_rects[0], test_rects.size()); | 276 &test_rects[0], test_rects.size()); |
275 } | 277 } |
276 } | 278 } |
277 } | 279 } |
278 } | 280 } |
279 | 281 |
280 static void TestEncodeDecodeRects(VideoEncoder* encoder, | 282 static void TestEncodeDecodeRects(VideoEncoder* encoder, |
281 VideoEncoderTester* encoder_tester, | 283 VideoEncoderTester* encoder_tester, |
282 VideoDecoderTester* decoder_tester, | 284 VideoDecoderTester* decoder_tester, |
283 webrtc::DesktopFrame* frame, | 285 DesktopFrame* frame, |
284 const DesktopRect* rects, int count) { | 286 const DesktopRect* rects, int count) { |
285 frame->mutable_updated_region()->Clear(); | 287 frame->mutable_updated_region()->Clear(); |
286 for (int i = 0; i < count; ++i) { | 288 for (int i = 0; i < count; ++i) { |
287 frame->mutable_updated_region()->AddRect(rects[i]); | 289 frame->mutable_updated_region()->AddRect(rects[i]); |
288 } | 290 } |
289 decoder_tester->AddRects(rects, count); | 291 decoder_tester->AddRects(rects, count); |
290 | 292 |
291 // Generate random data for the updated region. | 293 // Generate random data for the updated region. |
292 srand(0); | 294 srand(0); |
293 for (int i = 0; i < count; ++i) { | 295 for (int i = 0; i < count; ++i) { |
294 const int row_size = | 296 const int row_size = |
295 webrtc::DesktopFrame::kBytesPerPixel * rects[i].width(); | 297 DesktopFrame::kBytesPerPixel * rects[i].width(); |
296 uint8* memory = frame->data() + | 298 uint8* memory = frame->data() + |
297 frame->stride() * rects[i].top() + | 299 frame->stride() * rects[i].top() + |
298 webrtc::DesktopFrame::kBytesPerPixel * rects[i].left(); | 300 DesktopFrame::kBytesPerPixel * rects[i].left(); |
299 for (int y = 0; y < rects[i].height(); ++y) { | 301 for (int y = 0; y < rects[i].height(); ++y) { |
300 for (int x = 0; x < row_size; ++x) | 302 for (int x = 0; x < row_size; ++x) |
301 memory[x] = rand() % 256; | 303 memory[x] = rand() % 256; |
302 memory += frame->stride(); | 304 memory += frame->stride(); |
303 } | 305 } |
304 } | 306 } |
305 | 307 |
306 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); | 308 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); |
307 encoder_tester->DataAvailable(packet.Pass()); | 309 encoder_tester->DataAvailable(packet.Pass()); |
308 decoder_tester->VerifyResults(); | 310 decoder_tester->VerifyResults(); |
309 decoder_tester->Reset(); | 311 decoder_tester->Reset(); |
310 } | 312 } |
311 | 313 |
312 void TestVideoEncoderDecoder( | 314 void TestVideoEncoderDecoder( |
313 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { | 315 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { |
314 DesktopSize kSize = DesktopSize(320, 240); | 316 DesktopSize kSize = DesktopSize(320, 240); |
315 | 317 |
316 VideoEncoderTester encoder_tester; | 318 VideoEncoderTester encoder_tester; |
317 | 319 |
318 scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(kSize); | 320 scoped_ptr<DesktopFrame> frame = PrepareFrame(kSize); |
319 | 321 |
320 VideoDecoderTester decoder_tester(decoder, kSize, kSize); | 322 VideoDecoderTester decoder_tester(decoder, kSize, kSize); |
321 decoder_tester.set_strict(strict); | 323 decoder_tester.set_strict(strict); |
322 decoder_tester.set_frame(frame.get()); | 324 decoder_tester.set_frame(frame.get()); |
323 encoder_tester.set_decoder_tester(&decoder_tester); | 325 encoder_tester.set_decoder_tester(&decoder_tester); |
324 | 326 |
325 std::vector<std::vector<DesktopRect> > test_rect_lists = | 327 std::vector<std::vector<DesktopRect> > test_rect_lists = |
326 MakeTestRectLists(kSize); | 328 MakeTestRectLists(kSize); |
327 for (size_t i = 0; i < test_rect_lists.size(); ++i) { | 329 for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
328 const std::vector<DesktopRect> test_rects = test_rect_lists[i]; | 330 const std::vector<DesktopRect> test_rects = test_rect_lists[i]; |
329 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, | 331 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, |
330 frame.get(), &test_rects[0], test_rects.size()); | 332 frame.get(), &test_rects[0], test_rects.size()); |
331 } | 333 } |
332 } | 334 } |
333 | 335 |
334 static void FillWithGradient(webrtc::DesktopFrame* frame) { | 336 static void FillWithGradient(DesktopFrame* frame) { |
335 for (int j = 0; j < frame->size().height(); ++j) { | 337 for (int j = 0; j < frame->size().height(); ++j) { |
336 uint8* p = frame->data() + j * frame->stride(); | 338 uint8* p = frame->data() + j * frame->stride(); |
337 for (int i = 0; i < frame->size().width(); ++i) { | 339 for (int i = 0; i < frame->size().width(); ++i) { |
338 *p++ = (255.0 * i) / frame->size().width(); | 340 *p++ = (255.0 * i) / frame->size().width(); |
339 *p++ = (164.0 * j) / frame->size().height(); | 341 *p++ = (164.0 * j) / frame->size().height(); |
340 *p++ = (82.0 * (i + j)) / | 342 *p++ = (82.0 * (i + j)) / |
341 (frame->size().width() + frame->size().height()); | 343 (frame->size().width() + frame->size().height()); |
342 *p++ = 0; | 344 *p++ = 0; |
343 } | 345 } |
344 } | 346 } |
345 } | 347 } |
346 | 348 |
347 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, | 349 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, |
348 VideoDecoder* decoder, | 350 VideoDecoder* decoder, |
349 const DesktopSize& screen_size, | 351 const DesktopSize& screen_size, |
350 const DesktopSize& view_size, | 352 const DesktopSize& view_size, |
351 double max_error_limit, | 353 double max_error_limit, |
352 double mean_error_limit) { | 354 double mean_error_limit) { |
353 scoped_ptr<webrtc::BasicDesktopFrame> frame( | 355 scoped_ptr<BasicDesktopFrame> frame( |
354 new webrtc::BasicDesktopFrame(screen_size)); | 356 new BasicDesktopFrame(screen_size)); |
355 FillWithGradient(frame.get()); | 357 FillWithGradient(frame.get()); |
356 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(screen_size)); | 358 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(screen_size)); |
357 | 359 |
358 scoped_ptr<webrtc::BasicDesktopFrame> expected_result( | 360 scoped_ptr<BasicDesktopFrame> expected_result( |
359 new webrtc::BasicDesktopFrame(view_size)); | 361 new BasicDesktopFrame(view_size)); |
360 FillWithGradient(expected_result.get()); | 362 FillWithGradient(expected_result.get()); |
361 | 363 |
362 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); | 364 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); |
363 decoder_tester.set_frame(frame.get()); | 365 decoder_tester.set_frame(frame.get()); |
364 decoder_tester.AddRegion(frame->updated_region()); | 366 decoder_tester.AddRegion(frame->updated_region()); |
365 | 367 |
366 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); | 368 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); |
367 decoder_tester.ReceivedScopedPacket(packet.Pass()); | 369 decoder_tester.ReceivedScopedPacket(packet.Pass()); |
368 | 370 |
369 decoder_tester.VerifyResultsApprox(expected_result->data(), | 371 decoder_tester.VerifyResultsApprox(expected_result->data(), |
370 max_error_limit, mean_error_limit); | 372 max_error_limit, mean_error_limit); |
371 | 373 |
372 // Check that the decoder correctly re-renders the frame if its client | 374 // Check that the decoder correctly re-renders the frame if its client |
373 // invalidates the frame. | 375 // invalidates the frame. |
374 decoder_tester.ResetRenderedData(); | 376 decoder_tester.ResetRenderedData(); |
375 decoder->Invalidate( | 377 decoder->Invalidate( |
376 webrtc::DesktopSize(view_size.width(), view_size.height()), | 378 DesktopSize(view_size.width(), view_size.height()), |
377 webrtc::DesktopRegion( | 379 DesktopRegion( |
378 webrtc::DesktopRect::MakeWH(view_size.width(), view_size.height()))); | 380 DesktopRect::MakeWH(view_size.width(), view_size.height()))); |
379 decoder_tester.RenderFrame(); | 381 decoder_tester.RenderFrame(); |
380 decoder_tester.VerifyResultsApprox(expected_result->data(), | 382 decoder_tester.VerifyResultsApprox(expected_result->data(), |
381 max_error_limit, mean_error_limit); | 383 max_error_limit, mean_error_limit); |
382 } | 384 } |
383 | 385 |
| 386 float MeasureVideoEncoderFpsWithSize(VideoEncoder* encoder, |
| 387 const DesktopSize& size) { |
| 388 scoped_ptr<DesktopFrame> frame(PrepareFrame(size)); |
| 389 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(size)); |
| 390 std::list<DesktopFrame*> frames; |
| 391 frames.push_back(frame.get()); |
| 392 return MeasureVideoEncoderFpsWithFrames(encoder, frames); |
| 393 } |
| 394 |
| 395 float MeasureVideoEncoderFpsWithFrames(VideoEncoder* encoder, |
| 396 const std::list<DesktopFrame*>& frames) { |
| 397 const base::TimeDelta kTestTime = base::TimeDelta::FromSeconds(1); |
| 398 |
| 399 // Encode some frames to "warm up" the encoder (i.e. to let it set up initial |
| 400 // structures, establish a stable working set, etc), then encode at least |
| 401 // kMinimumFrameCount frames to measure the encoder's performance. |
| 402 const int kWarmUpFrameCount = 10; |
| 403 const int kMinimumFrameCount = 10; |
| 404 base::TimeTicks start_time; |
| 405 base::TimeDelta elapsed; |
| 406 std::list<DesktopFrame*> test_frames; |
| 407 int frame_count; |
| 408 for (frame_count = 0; |
| 409 (frame_count < kMinimumFrameCount + kWarmUpFrameCount || |
| 410 elapsed < kTestTime); |
| 411 ++frame_count) { |
| 412 if (frame_count == kWarmUpFrameCount) { |
| 413 start_time = base::TimeTicks::Now(); |
| 414 } |
| 415 |
| 416 if (test_frames.empty()) { |
| 417 test_frames = frames; |
| 418 } |
| 419 scoped_ptr<VideoPacket> packet = encoder->Encode(*test_frames.front()); |
| 420 test_frames.pop_front(); |
| 421 |
| 422 if (frame_count >= kWarmUpFrameCount) { |
| 423 elapsed = base::TimeTicks::Now() - start_time; |
| 424 } |
| 425 } |
| 426 |
| 427 return (frame_count * base::TimeDelta::FromSeconds(1)) / elapsed; |
| 428 } |
| 429 |
384 } // namespace remoting | 430 } // namespace remoting |
OLD | NEW |