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 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 const int kBytesPerPixel = 4; | 21 const int kBytesPerPixel = 4; |
| 21 | 22 |
| 22 // Some sample rects for testing. | 23 // Some sample rects for testing. |
| 23 std::vector<std::vector<SkIRect> > MakeTestRectLists(const SkISize& size) { | 24 std::vector<std::vector<webrtc::DesktopRect> > MakeTestRectLists( |
|
Wez
2013/04/26 18:48:14
nit: You could reasonably using webrtc::DesktopRec
Sergey Ulanov
2013/05/07 22:25:50
Done.
| |
| 24 std::vector<std::vector<SkIRect> > rect_lists; | 25 webrtc::DesktopSize size) { |
| 25 std::vector<SkIRect> rects; | 26 std::vector<std::vector<webrtc::DesktopRect> > rect_lists; |
| 26 rects.push_back(SkIRect::MakeXYWH(0, 0, size.width(), size.height())); | 27 std::vector<webrtc::DesktopRect> rects; |
| 28 rects.push_back(webrtc::DesktopRect::MakeXYWH( | |
| 29 0, 0, size.width(), size.height())); | |
| 27 rect_lists.push_back(rects); | 30 rect_lists.push_back(rects); |
| 28 rects.clear(); | 31 rects.clear(); |
| 29 rects.push_back(SkIRect::MakeXYWH(0, 0, size.width() / 2, size.height() / 2)); | 32 rects.push_back(webrtc::DesktopRect::MakeXYWH( |
| 33 0, 0, size.width() / 2, size.height() / 2)); | |
| 30 rect_lists.push_back(rects); | 34 rect_lists.push_back(rects); |
| 31 rects.clear(); | 35 rects.clear(); |
| 32 rects.push_back(SkIRect::MakeXYWH(size.width() / 2, size.height() / 2, | 36 rects.push_back(webrtc::DesktopRect::MakeXYWH( |
| 33 size.width() / 2, size.height() / 2)); | 37 size.width() / 2, size.height() / 2, |
| 38 size.width() / 2, size.height() / 2)); | |
| 34 rect_lists.push_back(rects); | 39 rect_lists.push_back(rects); |
| 35 rects.clear(); | 40 rects.clear(); |
| 36 rects.push_back(SkIRect::MakeXYWH(16, 16, 16, 16)); | 41 rects.push_back(webrtc::DesktopRect::MakeXYWH(16, 16, 16, 16)); |
| 37 rects.push_back(SkIRect::MakeXYWH(128, 64, 32, 32)); | 42 rects.push_back(webrtc::DesktopRect::MakeXYWH(128, 64, 32, 32)); |
| 38 rect_lists.push_back(rects); | 43 rect_lists.push_back(rects); |
| 39 return rect_lists; | 44 return rect_lists; |
| 40 } | 45 } |
| 41 | 46 |
| 42 } // namespace | 47 } // namespace |
| 43 | 48 |
| 44 namespace remoting { | 49 namespace remoting { |
| 45 | 50 |
| 46 // A class to test the message output of the encoder. | 51 // A class to test the message output of the encoder. |
| 47 class VideoEncoderMessageTester { | 52 class VideoEncoderMessageTester { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 65 } | 70 } |
| 66 | 71 |
| 67 // Test that we received the correct packet. | 72 // Test that we received the correct packet. |
| 68 void ReceivedPacket(VideoPacket* packet) { | 73 void ReceivedPacket(VideoPacket* packet) { |
| 69 if (state_ == kWaitingForBeginRect) { | 74 if (state_ == kWaitingForBeginRect) { |
| 70 EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); | 75 EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); |
| 71 state_ = kWaitingForRectData; | 76 state_ = kWaitingForRectData; |
| 72 ++begin_rect_; | 77 ++begin_rect_; |
| 73 | 78 |
| 74 if (strict_) { | 79 if (strict_) { |
| 75 SkIRect rect = rects_.front(); | 80 webrtc::DesktopRect rect = rects_.front(); |
| 76 rects_.pop_front(); | 81 rects_.pop_front(); |
| 77 EXPECT_EQ(rect.fLeft, packet->format().x()); | 82 EXPECT_EQ(rect.left(), packet->format().x()); |
| 78 EXPECT_EQ(rect.fTop, packet->format().y()); | 83 EXPECT_EQ(rect.top(), packet->format().y()); |
| 79 EXPECT_EQ(rect.width(), packet->format().width()); | 84 EXPECT_EQ(rect.width(), packet->format().width()); |
| 80 EXPECT_EQ(rect.height(), packet->format().height()); | 85 EXPECT_EQ(rect.height(), packet->format().height()); |
| 81 } | 86 } |
| 82 } else { | 87 } else { |
| 83 EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); | 88 EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); |
| 84 } | 89 } |
| 85 | 90 |
| 86 if (state_ == kWaitingForRectData) { | 91 if (state_ == kWaitingForRectData) { |
| 87 if (packet->has_data()) { | 92 if (packet->has_data()) { |
| 88 ++rect_data_; | 93 ++rect_data_; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 100 // LAST_PARTITION must always be marked with LAST_PACKET. | 105 // LAST_PARTITION must always be marked with LAST_PACKET. |
| 101 EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0); | 106 EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0); |
| 102 } | 107 } |
| 103 } | 108 } |
| 104 } | 109 } |
| 105 | 110 |
| 106 void set_strict(bool strict) { | 111 void set_strict(bool strict) { |
| 107 strict_ = strict; | 112 strict_ = strict; |
| 108 } | 113 } |
| 109 | 114 |
| 110 void AddRects(const SkIRect* rects, int count) { | 115 void AddRects(const webrtc::DesktopRect* rects, int count) { |
| 111 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); | 116 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); |
| 112 added_rects_ += count; | 117 added_rects_ += count; |
| 113 } | 118 } |
| 114 | 119 |
| 115 private: | 120 private: |
| 116 enum State { | 121 enum State { |
| 117 kWaitingForBeginRect, | 122 kWaitingForBeginRect, |
| 118 kWaitingForRectData, | 123 kWaitingForRectData, |
| 119 }; | 124 }; |
| 120 | 125 |
| 121 int begin_rect_; | 126 int begin_rect_; |
| 122 int rect_data_; | 127 int rect_data_; |
| 123 int end_rect_; | 128 int end_rect_; |
| 124 int added_rects_; | 129 int added_rects_; |
| 125 State state_; | 130 State state_; |
| 126 bool strict_; | 131 bool strict_; |
| 127 | 132 |
| 128 std::deque<SkIRect> rects_; | 133 std::deque<webrtc::DesktopRect> rects_; |
| 129 | 134 |
| 130 DISALLOW_COPY_AND_ASSIGN(VideoEncoderMessageTester); | 135 DISALLOW_COPY_AND_ASSIGN(VideoEncoderMessageTester); |
| 131 }; | 136 }; |
| 132 | 137 |
| 133 class VideoDecoderTester { | 138 class VideoDecoderTester { |
| 134 public: | 139 public: |
| 135 VideoDecoderTester(VideoDecoder* decoder, const SkISize& screen_size, | 140 VideoDecoderTester(VideoDecoder* decoder, |
| 136 const SkISize& view_size) | 141 const webrtc::DesktopSize& screen_size, |
| 142 const webrtc::DesktopSize& view_size) | |
| 137 : screen_size_(screen_size), | 143 : screen_size_(screen_size), |
| 138 view_size_(view_size), | 144 view_size_(view_size), |
| 139 strict_(false), | 145 strict_(false), |
| 140 decoder_(decoder) { | 146 decoder_(decoder) { |
| 141 image_data_.reset(new uint8[ | 147 image_data_.reset(new uint8[ |
| 142 view_size_.width() * view_size_.height() * kBytesPerPixel]); | 148 view_size_.width() * view_size_.height() * kBytesPerPixel]); |
| 143 EXPECT_TRUE(image_data_.get()); | 149 EXPECT_TRUE(image_data_.get()); |
| 144 decoder_->Initialize(screen_size_); | 150 decoder_->Initialize( |
| 151 SkISize::Make(screen_size_.width(), screen_size_.height())); | |
| 145 } | 152 } |
| 146 | 153 |
| 147 void Reset() { | 154 void Reset() { |
| 148 expected_region_.setEmpty(); | 155 expected_region_.Clear(); |
| 149 update_region_.setEmpty(); | 156 update_region_.setEmpty(); |
| 150 } | 157 } |
| 151 | 158 |
| 152 void ResetRenderedData() { | 159 void ResetRenderedData() { |
| 153 memset(image_data_.get(), 0, | 160 memset(image_data_.get(), 0, |
| 154 view_size_.width() * view_size_.height() * kBytesPerPixel); | 161 view_size_.width() * view_size_.height() * kBytesPerPixel); |
| 155 } | 162 } |
| 156 | 163 |
| 157 void ReceivedPacket(VideoPacket* packet) { | 164 void ReceivedPacket(VideoPacket* packet) { |
| 158 VideoDecoder::DecodeResult result = decoder_->DecodePacket(packet); | 165 VideoDecoder::DecodeResult result = decoder_->DecodePacket(packet); |
| 159 | 166 |
| 160 ASSERT_NE(VideoDecoder::DECODE_ERROR, result); | 167 ASSERT_NE(VideoDecoder::DECODE_ERROR, result); |
| 161 | 168 |
| 162 if (result == VideoDecoder::DECODE_DONE) { | 169 if (result == VideoDecoder::DECODE_DONE) { |
| 163 RenderFrame(); | 170 RenderFrame(); |
| 164 } | 171 } |
| 165 } | 172 } |
| 166 | 173 |
| 167 void RenderFrame() { | 174 void RenderFrame() { |
| 168 decoder_->RenderFrame(view_size_, | 175 decoder_->RenderFrame( |
| 169 SkIRect::MakeSize(view_size_), | 176 SkISize::Make(view_size_.width(), view_size_.height()), |
| 170 image_data_.get(), | 177 SkIRect::MakeWH(view_size_.width(), view_size_.height()), |
| 171 view_size_.width() * kBytesPerPixel, | 178 image_data_.get(), |
| 172 &update_region_); | 179 view_size_.width() * kBytesPerPixel, |
| 180 &update_region_); | |
| 173 } | 181 } |
| 174 | 182 |
| 175 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { | 183 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
| 176 ReceivedPacket(packet.get()); | 184 ReceivedPacket(packet.get()); |
| 177 } | 185 } |
| 178 | 186 |
| 179 void set_strict(bool strict) { | 187 void set_strict(bool strict) { |
| 180 strict_ = strict; | 188 strict_ = strict; |
| 181 } | 189 } |
| 182 | 190 |
| 183 void set_capture_data(scoped_refptr<media::ScreenCaptureData> data) { | 191 void set_frame(webrtc::DesktopFrame* frame) { |
| 184 capture_data_ = data; | 192 frame_ = frame; |
| 185 } | 193 } |
| 186 | 194 |
| 187 void AddRects(const SkIRect* rects, int count) { | 195 void AddRects(const webrtc::DesktopRect* rects, int count) { |
| 188 SkRegion new_rects; | 196 for (int i = 0; i < count; ++i) { |
| 189 new_rects.setRects(rects, count); | 197 expected_region_.AddRect(rects[i]); |
| 190 AddRegion(new_rects); | 198 } |
| 191 } | 199 } |
| 192 | 200 |
| 193 void AddRegion(const SkRegion& region) { | 201 void AddRegion(const webrtc::DesktopRegion& region) { |
| 194 expected_region_.op(region, SkRegion::kUnion_Op); | 202 expected_region_.AddRegion(region); |
| 195 } | 203 } |
| 196 | 204 |
| 197 void VerifyResults() { | 205 void VerifyResults() { |
| 198 if (!strict_) | 206 if (!strict_) |
| 199 return; | 207 return; |
| 200 | 208 |
| 201 ASSERT_TRUE(capture_data_.get()); | 209 ASSERT_TRUE(frame_); |
| 202 | 210 |
| 203 // Test the content of the update region. | 211 // Test the content of the update region. |
| 204 EXPECT_EQ(expected_region_, update_region_); | 212 SkRegion expected_region; |
| 213 for (webrtc::DesktopRegion::Iterator it(expected_region_); | |
| 214 !it.IsAtEnd(); it.Advance()) { | |
| 215 expected_region.op( | |
| 216 SkIRect::MakeXYWH(it.rect().top(), it.rect().left(), | |
| 217 it.rect().width(), it.rect().height()), | |
| 218 SkRegion::kUnion_Op); | |
| 219 } | |
| 220 EXPECT_EQ(expected_region, update_region_); | |
|
alexeypa (please no reviews)
2013/04/26 21:33:58
nit: Add a TODO here to get rid of SkRegion here.
Sergey Ulanov
2013/05/07 22:25:50
Added TODO.
The reason SkRegion still needs to be
| |
| 221 | |
| 205 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { | 222 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
| 206 const int stride = view_size_.width() * kBytesPerPixel; | 223 const int stride = view_size_.width() * kBytesPerPixel; |
| 207 EXPECT_EQ(stride, capture_data_->stride()); | 224 EXPECT_EQ(stride, frame_->stride()); |
| 208 const int offset = stride * i.rect().top() + | 225 const int offset = stride * i.rect().top() + |
| 209 kBytesPerPixel * i.rect().left(); | 226 kBytesPerPixel * i.rect().left(); |
| 210 const uint8* original = capture_data_->data() + offset; | 227 const uint8* original = frame_->data() + offset; |
| 211 const uint8* decoded = image_data_.get() + offset; | 228 const uint8* decoded = image_data_.get() + offset; |
| 212 const int row_size = kBytesPerPixel * i.rect().width(); | 229 const int row_size = kBytesPerPixel * i.rect().width(); |
| 213 for (int y = 0; y < i.rect().height(); ++y) { | 230 for (int y = 0; y < i.rect().height(); ++y) { |
| 214 EXPECT_EQ(0, memcmp(original, decoded, row_size)) | 231 EXPECT_EQ(0, memcmp(original, decoded, row_size)) |
| 215 << "Row " << y << " is different"; | 232 << "Row " << y << " is different"; |
| 216 original += stride; | 233 original += stride; |
| 217 decoded += stride; | 234 decoded += stride; |
| 218 } | 235 } |
| 219 } | 236 } |
| 220 } | 237 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 static_cast<double>(*decoded++); | 275 static_cast<double>(*decoded++); |
| 259 error /= 255.0; | 276 error /= 255.0; |
| 260 error_sum_squares += error * error; | 277 error_sum_squares += error * error; |
| 261 } | 278 } |
| 262 original++; | 279 original++; |
| 263 decoded++; | 280 decoded++; |
| 264 return sqrt(error_sum_squares / 3.0); | 281 return sqrt(error_sum_squares / 3.0); |
| 265 } | 282 } |
| 266 | 283 |
| 267 private: | 284 private: |
| 268 SkISize screen_size_; | 285 webrtc::DesktopSize screen_size_; |
| 269 SkISize view_size_; | 286 webrtc::DesktopSize view_size_; |
| 270 bool strict_; | 287 bool strict_; |
| 271 SkRegion expected_region_; | 288 webrtc::DesktopRegion expected_region_; |
| 272 SkRegion update_region_; | 289 SkRegion update_region_; |
| 273 VideoDecoder* decoder_; | 290 VideoDecoder* decoder_; |
| 274 scoped_ptr<uint8[]> image_data_; | 291 scoped_ptr<uint8[]> image_data_; |
| 275 scoped_refptr<media::ScreenCaptureData> capture_data_; | 292 webrtc::DesktopFrame* frame_; |
| 276 | 293 |
| 277 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); | 294 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); |
| 278 }; | 295 }; |
| 279 | 296 |
| 280 // The VideoEncoderTester provides a hook for retrieving the data, and passing | 297 // The VideoEncoderTester provides a hook for retrieving the data, and passing |
| 281 // the message to other subprograms for validaton. | 298 // the message to other subprograms for validaton. |
| 282 class VideoEncoderTester { | 299 class VideoEncoderTester { |
| 283 public: | 300 public: |
| 284 VideoEncoderTester(VideoEncoderMessageTester* message_tester) | 301 VideoEncoderTester(VideoEncoderMessageTester* message_tester) |
| 285 : message_tester_(message_tester), | 302 : message_tester_(message_tester), |
| 286 decoder_tester_(NULL), | 303 decoder_tester_(NULL), |
| 287 data_available_(0) { | 304 data_available_(0) { |
| 288 } | 305 } |
| 289 | 306 |
| 290 ~VideoEncoderTester() { | 307 ~VideoEncoderTester() { |
| 291 EXPECT_GT(data_available_, 0); | 308 EXPECT_GT(data_available_, 0); |
| 292 } | 309 } |
| 293 | 310 |
| 294 void DataAvailable(scoped_ptr<VideoPacket> packet) { | 311 void DataAvailable(scoped_ptr<VideoPacket> packet) { |
| 295 ++data_available_; | 312 ++data_available_; |
| 296 message_tester_->ReceivedPacket(packet.get()); | 313 message_tester_->ReceivedPacket(packet.get()); |
| 297 | 314 |
| 298 // Send the message to the VideoDecoderTester. | 315 // Send the message to the VideoDecoderTester. |
| 299 if (decoder_tester_) { | 316 if (decoder_tester_) { |
| 300 decoder_tester_->ReceivedPacket(packet.get()); | 317 decoder_tester_->ReceivedPacket(packet.get()); |
| 301 } | 318 } |
| 302 } | 319 } |
| 303 | 320 |
| 304 void AddRects(const SkIRect* rects, int count) { | 321 void AddRects(const webrtc::DesktopRect* rects, int count) { |
| 305 message_tester_->AddRects(rects, count); | 322 message_tester_->AddRects(rects, count); |
| 306 } | 323 } |
| 307 | 324 |
| 308 void set_decoder_tester(VideoDecoderTester* decoder_tester) { | 325 void set_decoder_tester(VideoDecoderTester* decoder_tester) { |
| 309 decoder_tester_ = decoder_tester; | 326 decoder_tester_ = decoder_tester; |
| 310 } | 327 } |
| 311 | 328 |
| 312 private: | 329 private: |
| 313 VideoEncoderMessageTester* message_tester_; | 330 VideoEncoderMessageTester* message_tester_; |
| 314 VideoDecoderTester* decoder_tester_; | 331 VideoDecoderTester* decoder_tester_; |
| 315 int data_available_; | 332 int data_available_; |
| 316 | 333 |
| 317 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); | 334 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); |
| 318 }; | 335 }; |
| 319 | 336 |
| 320 scoped_refptr<media::ScreenCaptureData> PrepareEncodeData( | 337 scoped_ptr<webrtc::DesktopFrame> PrepareFrame(const webrtc::DesktopSize& size) { |
| 321 const SkISize& size, | 338 scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size)); |
| 322 scoped_ptr<uint8[]>* memory) { | |
| 323 int memory_size = size.width() * size.height() * kBytesPerPixel; | |
| 324 | |
| 325 memory->reset(new uint8[memory_size]); | |
| 326 | 339 |
| 327 srand(0); | 340 srand(0); |
| 341 int memory_size = size.width() * size.height() * kBytesPerPixel; | |
| 328 for (int i = 0; i < memory_size; ++i) { | 342 for (int i = 0; i < memory_size; ++i) { |
| 329 (*memory)[i] = rand() % 256; | 343 frame->data()[i] = rand() % 256; |
| 330 } | 344 } |
| 331 | 345 |
| 332 scoped_refptr<media::ScreenCaptureData> data = new media::ScreenCaptureData( | 346 return frame.Pass(); |
| 333 memory->get(), size.width() * kBytesPerPixel, size); | |
| 334 return data; | |
| 335 } | 347 } |
| 336 | 348 |
| 337 static void TestEncodingRects(VideoEncoder* encoder, | 349 static void TestEncodingRects(VideoEncoder* encoder, |
| 338 VideoEncoderTester* tester, | 350 VideoEncoderTester* tester, |
| 339 scoped_refptr<media::ScreenCaptureData> data, | 351 webrtc::DesktopFrame* frame, |
| 340 const SkIRect* rects, int count) { | 352 const webrtc::DesktopRect* rects, |
| 341 data->mutable_dirty_region().setEmpty(); | 353 int count) { |
| 354 frame->mutable_updated_region()->Clear(); | |
| 342 for (int i = 0; i < count; ++i) { | 355 for (int i = 0; i < count; ++i) { |
| 343 data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op); | 356 frame->mutable_updated_region()->AddRect(rects[i]); |
| 344 } | 357 } |
| 345 tester->AddRects(rects, count); | 358 tester->AddRects(rects, count); |
| 346 | 359 |
| 347 encoder->Encode(data, true, base::Bind( | 360 encoder->Encode(frame, base::Bind( |
| 348 &VideoEncoderTester::DataAvailable, base::Unretained(tester))); | 361 &VideoEncoderTester::DataAvailable, base::Unretained(tester))); |
| 349 } | 362 } |
| 350 | 363 |
| 351 void TestVideoEncoder(VideoEncoder* encoder, bool strict) { | 364 void TestVideoEncoder(VideoEncoder* encoder, bool strict) { |
| 352 const int kSizes[] = {320, 319, 317, 150}; | 365 const int kSizes[] = {320, 319, 317, 150}; |
| 353 | 366 |
| 354 VideoEncoderMessageTester message_tester; | 367 VideoEncoderMessageTester message_tester; |
| 355 message_tester.set_strict(strict); | 368 message_tester.set_strict(strict); |
| 356 | 369 |
| 357 VideoEncoderTester tester(&message_tester); | 370 VideoEncoderTester tester(&message_tester); |
| 358 | 371 |
| 359 scoped_ptr<uint8[]> memory; | |
| 360 | |
| 361 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { | 372 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { |
| 362 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { | 373 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { |
| 363 SkISize size = SkISize::Make(kSizes[xi], kSizes[yi]); | 374 webrtc::DesktopSize size = webrtc::DesktopSize(kSizes[xi], kSizes[yi]); |
| 364 scoped_refptr<media::ScreenCaptureData> data = | 375 scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(size); |
| 365 PrepareEncodeData(size, &memory); | 376 std::vector<std::vector<webrtc::DesktopRect> > test_rect_lists = |
| 366 std::vector<std::vector<SkIRect> > test_rect_lists = | |
| 367 MakeTestRectLists(size); | 377 MakeTestRectLists(size); |
| 368 for (size_t i = 0; i < test_rect_lists.size(); ++i) { | 378 for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
| 369 const std::vector<SkIRect>& test_rects = test_rect_lists[i]; | 379 const std::vector<webrtc::DesktopRect>& test_rects = test_rect_lists[i]; |
| 370 TestEncodingRects(encoder, &tester, data, | 380 TestEncodingRects(encoder, &tester, frame.get(), |
| 371 &test_rects[0], test_rects.size()); | 381 &test_rects[0], test_rects.size()); |
| 372 } | 382 } |
| 373 } | 383 } |
| 374 } | 384 } |
| 375 } | 385 } |
| 376 | 386 |
| 377 static void TestEncodeDecodeRects(VideoEncoder* encoder, | 387 static void TestEncodeDecodeRects(VideoEncoder* encoder, |
| 378 VideoEncoderTester* encoder_tester, | 388 VideoEncoderTester* encoder_tester, |
| 379 VideoDecoderTester* decoder_tester, | 389 VideoDecoderTester* decoder_tester, |
| 380 scoped_refptr<media::ScreenCaptureData> data, | 390 webrtc::DesktopFrame* frame, |
| 381 const SkIRect* rects, int count) { | 391 const webrtc::DesktopRect* rects, int count) { |
| 382 data->mutable_dirty_region().setRects(rects, count); | 392 frame->mutable_updated_region()->Clear(); |
| 393 for (int i = 0; i < count; ++i) { | |
| 394 frame->mutable_updated_region()->AddRect(rects[i]); | |
| 395 } | |
| 383 encoder_tester->AddRects(rects, count); | 396 encoder_tester->AddRects(rects, count); |
| 384 decoder_tester->AddRects(rects, count); | 397 decoder_tester->AddRects(rects, count); |
| 385 | 398 |
| 386 // Generate random data for the updated region. | 399 // Generate random data for the updated region. |
|
alexeypa (please no reviews)
2013/04/26 21:33:58
nit: Maybe clarify that the data is not random bet
Sergey Ulanov
2013/05/07 22:25:50
It's generated using rand(), thus it's random ;) .
alexeypa (please no reviews)
2013/05/08 22:24:59
The seed is fixed by srand(0) call. rand() will ge
Sergey Ulanov
2013/05/09 18:49:02
Yes, I understand it. Still think calling it "rand
| |
| 387 srand(0); | 400 srand(0); |
| 388 for (int i = 0; i < count; ++i) { | 401 for (int i = 0; i < count; ++i) { |
| 389 const int bytes_per_pixel = 4; // Because of RGB32 on previous line. | 402 const int row_size = |
| 390 const int row_size = bytes_per_pixel * rects[i].width(); | 403 webrtc::DesktopFrame::kBytesPerPixel * rects[i].width(); |
| 391 uint8* memory = data->data() + | 404 uint8* memory = frame->data() + |
| 392 data->stride() * rects[i].top() + | 405 frame->stride() * rects[i].top() + |
| 393 bytes_per_pixel * rects[i].left(); | 406 webrtc::DesktopFrame::kBytesPerPixel * rects[i].left(); |
| 394 for (int y = 0; y < rects[i].height(); ++y) { | 407 for (int y = 0; y < rects[i].height(); ++y) { |
| 395 for (int x = 0; x < row_size; ++x) | 408 for (int x = 0; x < row_size; ++x) |
| 396 memory[x] = rand() % 256; | 409 memory[x] = rand() % 256; |
| 397 memory += data->stride(); | 410 memory += frame->stride(); |
| 398 } | 411 } |
| 399 } | 412 } |
| 400 | 413 |
| 401 encoder->Encode(data, true, base::Bind(&VideoEncoderTester::DataAvailable, | 414 encoder->Encode(frame, base::Bind(&VideoEncoderTester::DataAvailable, |
| 402 base::Unretained(encoder_tester))); | 415 base::Unretained(encoder_tester))); |
| 403 decoder_tester->VerifyResults(); | 416 decoder_tester->VerifyResults(); |
| 404 decoder_tester->Reset(); | 417 decoder_tester->Reset(); |
| 405 } | 418 } |
| 406 | 419 |
| 407 void TestVideoEncoderDecoder( | 420 void TestVideoEncoderDecoder( |
| 408 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { | 421 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { |
| 409 SkISize kSize = SkISize::Make(320, 240); | 422 webrtc::DesktopSize kSize = webrtc::DesktopSize(320, 240); |
| 410 | 423 |
| 411 VideoEncoderMessageTester message_tester; | 424 VideoEncoderMessageTester message_tester; |
| 412 message_tester.set_strict(strict); | 425 message_tester.set_strict(strict); |
| 413 | 426 |
| 414 VideoEncoderTester encoder_tester(&message_tester); | 427 VideoEncoderTester encoder_tester(&message_tester); |
| 415 | 428 |
| 416 scoped_ptr<uint8[]> memory; | 429 scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(kSize); |
| 417 scoped_refptr<media::ScreenCaptureData> data = | |
| 418 PrepareEncodeData(kSize, &memory); | |
| 419 | 430 |
| 420 VideoDecoderTester decoder_tester(decoder, kSize, kSize); | 431 VideoDecoderTester decoder_tester(decoder, kSize, kSize); |
| 421 decoder_tester.set_strict(strict); | 432 decoder_tester.set_strict(strict); |
| 422 decoder_tester.set_capture_data(data); | 433 decoder_tester.set_frame(frame.get()); |
| 423 encoder_tester.set_decoder_tester(&decoder_tester); | 434 encoder_tester.set_decoder_tester(&decoder_tester); |
| 424 | 435 |
| 425 std::vector<std::vector<SkIRect> > test_rect_lists = MakeTestRectLists(kSize); | 436 std::vector<std::vector<webrtc::DesktopRect> > test_rect_lists = |
| 437 MakeTestRectLists(kSize); | |
| 426 for (size_t i = 0; i < test_rect_lists.size(); ++i) { | 438 for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
| 427 const std::vector<SkIRect> test_rects = test_rect_lists[i]; | 439 const std::vector<webrtc::DesktopRect> test_rects = test_rect_lists[i]; |
| 428 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 440 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, |
| 429 &test_rects[0], test_rects.size()); | 441 frame.get(), &test_rects[0], test_rects.size()); |
| 430 } | 442 } |
| 431 } | 443 } |
| 432 | 444 |
| 433 static void FillWithGradient(uint8* memory, const SkISize& frame_size, | 445 static void FillWithGradient(webrtc::DesktopFrame* frame) { |
| 434 const SkIRect& rect) { | 446 for (int j = 0; j < frame->size().height(); ++j) { |
| 435 for (int j = rect.top(); j < rect.bottom(); ++j) { | 447 uint8* p = frame->data() + j * frame->stride(); |
| 436 uint8* p = memory + ((j * frame_size.width()) + rect.left()) * 4; | 448 for (int i = 0; i < frame->size().width(); ++i) { |
| 437 for (int i = rect.left(); i < rect.right(); ++i) { | 449 *p++ = (255.0 * i) / frame->size().width(); |
|
alexeypa (please no reviews)
2013/04/26 21:33:58
nit: I suspect that the static_casts were used for
Sergey Ulanov
2013/05/07 22:25:50
I think it did compile on VC++, I'll add the casts
| |
| 438 *p++ = static_cast<uint8>((255.0 * i) / frame_size.width()); | 450 *p++ = (164.0 * j) / frame->size().height(); |
| 439 *p++ = static_cast<uint8>((164.0 * j) / frame_size.height()); | 451 *p++ = (82.0 * (i + j)) / |
| 440 *p++ = static_cast<uint8>((82.0 * (i + j)) / | 452 (frame->size().width() + frame->size().height()); |
| 441 (frame_size.width() + frame_size.height())); | |
| 442 *p++ = 0; | 453 *p++ = 0; |
| 443 } | 454 } |
| 444 } | 455 } |
| 445 } | 456 } |
| 446 | 457 |
| 447 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, | 458 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, |
| 448 VideoDecoder* decoder, | 459 VideoDecoder* decoder, |
| 449 const SkISize& screen_size, | 460 const webrtc::DesktopSize& screen_size, |
| 450 const SkISize& view_size, | 461 const webrtc::DesktopSize& view_size, |
| 451 double max_error_limit, | 462 double max_error_limit, |
| 452 double mean_error_limit) { | 463 double mean_error_limit) { |
| 453 SkIRect screen_rect = SkIRect::MakeSize(screen_size); | 464 scoped_ptr<webrtc::BasicDesktopFrame> frame( |
| 454 scoped_ptr<uint8[]> screen_data(new uint8[ | 465 new webrtc::BasicDesktopFrame(screen_size)); |
| 455 screen_size.width() * screen_size.height() * kBytesPerPixel]); | 466 FillWithGradient(frame.get()); |
| 456 FillWithGradient(screen_data.get(), screen_size, screen_rect); | 467 frame->mutable_updated_region()->SetRect( |
| 468 webrtc::DesktopRect::MakeSize(screen_size)); | |
| 457 | 469 |
| 458 SkIRect view_rect = SkIRect::MakeSize(view_size); | 470 scoped_ptr<webrtc::BasicDesktopFrame> expected_result( |
| 459 scoped_ptr<uint8[]> expected_view_data(new uint8[ | 471 new webrtc::BasicDesktopFrame(view_size)); |
| 460 view_size.width() * view_size.height() * kBytesPerPixel]); | 472 FillWithGradient(expected_result.get()); |
| 461 FillWithGradient(expected_view_data.get(), view_size, view_rect); | |
| 462 | |
| 463 scoped_refptr<media::ScreenCaptureData> capture_data = | |
| 464 new media::ScreenCaptureData( | |
| 465 screen_data.get(), screen_size.width() * kBytesPerPixel, screen_size); | |
| 466 capture_data->mutable_dirty_region().op(screen_rect, SkRegion::kUnion_Op); | |
| 467 | 473 |
| 468 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); | 474 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); |
| 469 decoder_tester.set_capture_data(capture_data); | 475 decoder_tester.set_frame(frame.get()); |
| 470 decoder_tester.AddRegion(capture_data->dirty_region()); | 476 decoder_tester.AddRegion(frame->updated_region()); |
| 471 | 477 |
| 472 encoder->Encode(capture_data, true, | 478 encoder->Encode(frame.get(), |
| 473 base::Bind(&VideoDecoderTester::ReceivedScopedPacket, | 479 base::Bind(&VideoDecoderTester::ReceivedScopedPacket, |
| 474 base::Unretained(&decoder_tester))); | 480 base::Unretained(&decoder_tester))); |
| 475 | 481 |
| 476 decoder_tester.VerifyResultsApprox(expected_view_data.get(), | 482 decoder_tester.VerifyResultsApprox(expected_result->data(), |
| 477 max_error_limit, mean_error_limit); | 483 max_error_limit, mean_error_limit); |
| 478 | 484 |
| 479 // Check that the decoder correctly re-renders the frame if its client | 485 // Check that the decoder correctly re-renders the frame if its client |
| 480 // invalidates the frame. | 486 // invalidates the frame. |
| 481 decoder_tester.ResetRenderedData(); | 487 decoder_tester.ResetRenderedData(); |
| 482 decoder->Invalidate(view_size, SkRegion(view_rect)); | 488 decoder->Invalidate( |
| 489 SkISize::Make(view_size.width(), view_size.height()), | |
| 490 SkRegion(SkIRect::MakeWH(view_size.width(), view_size.height()))); | |
| 483 decoder_tester.RenderFrame(); | 491 decoder_tester.RenderFrame(); |
| 484 decoder_tester.VerifyResultsApprox(expected_view_data.get(), | 492 decoder_tester.VerifyResultsApprox(expected_result->data(), |
| 485 max_error_limit, mean_error_limit); | 493 max_error_limit, mean_error_limit); |
| 486 } | 494 } |
| 487 | 495 |
| 488 } // namespace remoting | 496 } // namespace remoting |
| OLD | NEW |