Chromium Code Reviews| 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( | |
| 387 VideoEncoder* encoder, const DesktopSize& size) { | |
|
Sergey Ulanov
2014/06/24 02:00:51
nit: one argument per line please
Wez
2014/06/24 02:14:13
Done.
| |
| 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( | |
| 396 VideoEncoder* encoder, 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 |