| 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" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 140 |
| 141 if (result == Decoder::DECODE_DONE) { | 141 if (result == Decoder::DECODE_DONE) { |
| 142 decoder_->RenderFrame(SkISize::Make(kWidth, kHeight), | 142 decoder_->RenderFrame(SkISize::Make(kWidth, kHeight), |
| 143 SkIRect::MakeXYWH(0, 0, kWidth, kHeight), | 143 SkIRect::MakeXYWH(0, 0, kWidth, kHeight), |
| 144 image_data_.get(), | 144 image_data_.get(), |
| 145 kWidth * kBytesPerPixel, | 145 kWidth * kBytesPerPixel, |
| 146 &update_region_); | 146 &update_region_); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
| 151 ReceivedPacket(packet.get()); |
| 152 } |
| 153 |
| 150 void set_strict(bool strict) { | 154 void set_strict(bool strict) { |
| 151 strict_ = strict; | 155 strict_ = strict; |
| 152 } | 156 } |
| 153 | 157 |
| 154 void set_capture_data(scoped_refptr<CaptureData> data) { | 158 void set_capture_data(scoped_refptr<CaptureData> data) { |
| 155 capture_data_ = data; | 159 capture_data_ = data; |
| 156 } | 160 } |
| 157 | 161 |
| 158 void AddRects(const SkIRect* rects, int count) { | 162 void AddRects(const SkIRect* rects, int count) { |
| 159 SkRegion new_rects; | 163 SkRegion new_rects; |
| 160 new_rects.setRects(rects, count); | 164 new_rects.setRects(rects, count); |
| 161 expected_region_.op(new_rects, SkRegion::kUnion_Op); | 165 AddRegion(new_rects); |
| 166 } |
| 167 |
| 168 void AddRegion(const SkRegion& region) { |
| 169 expected_region_.op(region, SkRegion::kUnion_Op); |
| 162 } | 170 } |
| 163 | 171 |
| 164 void VerifyResults() { | 172 void VerifyResults() { |
| 165 if (!strict_) | 173 if (!strict_) |
| 166 return; | 174 return; |
| 167 | 175 |
| 168 ASSERT_TRUE(capture_data_.get()); | 176 ASSERT_TRUE(capture_data_.get()); |
| 169 | 177 |
| 170 // Test the content of the update region. | 178 // Test the content of the update region. |
| 171 EXPECT_EQ(expected_region_, update_region_); | 179 EXPECT_EQ(expected_region_, update_region_); |
| 172 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { | 180 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
| 173 const int stride = kWidth * kBytesPerPixel; | 181 const int stride = kWidth * kBytesPerPixel; |
| 174 EXPECT_EQ(stride, capture_data_->data_planes().strides[0]); | 182 EXPECT_EQ(stride, capture_data_->data_planes().strides[0]); |
| 175 const int offset = stride * i.rect().top() + | 183 const int offset = stride * i.rect().top() + |
| 176 kBytesPerPixel * i.rect().left(); | 184 kBytesPerPixel * i.rect().left(); |
| 177 const uint8* original = capture_data_->data_planes().data[0] + offset; | 185 const uint8* original = capture_data_->data_planes().data[0] + offset; |
| 178 const uint8* decoded = image_data_.get() + offset; | 186 const uint8* decoded = image_data_.get() + offset; |
| 179 const int row_size = kBytesPerPixel * i.rect().width(); | 187 const int row_size = kBytesPerPixel * i.rect().width(); |
| 180 for (int y = 0; y < i.rect().height(); ++y) { | 188 for (int y = 0; y < i.rect().height(); ++y) { |
| 181 EXPECT_EQ(0, memcmp(original, decoded, row_size)) | 189 EXPECT_EQ(0, memcmp(original, decoded, row_size)) |
| 182 << "Row " << y << " is different"; | 190 << "Row " << y << " is different"; |
| 183 original += stride; | 191 original += stride; |
| 184 decoded += stride; | 192 decoded += stride; |
| 185 } | 193 } |
| 186 } | 194 } |
| 187 } | 195 } |
| 188 | 196 |
| 197 // The error at each pixel is the root mean square of the errors in |
| 198 // the R, G, and B components, each normalized to [0, 1]. This routine |
| 199 // checks that the maximum and mean pixel errors do not exceed given limits. |
| 200 void VerifyResultsApprox(double max_error_limit, double mean_error_limit) { |
| 201 ASSERT_TRUE(capture_data_.get()); |
| 202 |
| 203 // Test the content of the update region. |
| 204 EXPECT_EQ(expected_region_, update_region_); |
| 205 double max_error = 0.0; |
| 206 double sum_error = 0.0; |
| 207 int error_num = 0; |
| 208 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
| 209 const int stride = kWidth * kBytesPerPixel; |
| 210 EXPECT_EQ(stride, capture_data_->data_planes().strides[0]); |
| 211 const int offset = stride * i.rect().top() + |
| 212 kBytesPerPixel * i.rect().left(); |
| 213 const uint8* original = capture_data_->data_planes().data[0] + offset; |
| 214 const uint8* decoded = image_data_.get() + offset; |
| 215 for (int y = 0; y < i.rect().height(); ++y) { |
| 216 for (int x = 0; x < i.rect().width(); ++x) { |
| 217 double error = CalculateError(original, decoded); |
| 218 max_error = std::max(max_error, error); |
| 219 sum_error += error; |
| 220 ++error_num; |
| 221 original += 4; |
| 222 decoded += 4; |
| 223 } |
| 224 } |
| 225 } |
| 226 EXPECT_LE(max_error, max_error_limit); |
| 227 double mean_error = sum_error / error_num; |
| 228 EXPECT_LE(mean_error, mean_error_limit); |
| 229 LOG(INFO) << "Max error: " << max_error; |
| 230 LOG(INFO) << "Mean error: " << mean_error; |
| 231 } |
| 232 |
| 233 double CalculateError(const uint8* original, const uint8* decoded) { |
| 234 double error_sum_squares = 0.0; |
| 235 for (int i = 0; i < 3; i++) { |
| 236 double error = static_cast<double>(*original++) - |
| 237 static_cast<double>(*decoded++); |
| 238 error /= 255.0; |
| 239 error_sum_squares += error * error; |
| 240 } |
| 241 original++; |
| 242 decoded++; |
| 243 return sqrt(error_sum_squares / 3.0); |
| 244 } |
| 245 |
| 189 private: | 246 private: |
| 190 bool strict_; | 247 bool strict_; |
| 191 SkRegion expected_region_; | 248 SkRegion expected_region_; |
| 192 SkRegion update_region_; | 249 SkRegion update_region_; |
| 193 Decoder* decoder_; | 250 Decoder* decoder_; |
| 194 scoped_array<uint8> image_data_; | 251 scoped_array<uint8> image_data_; |
| 195 scoped_refptr<CaptureData> capture_data_; | 252 scoped_refptr<CaptureData> capture_data_; |
| 196 | 253 |
| 197 DISALLOW_COPY_AND_ASSIGN(DecoderTester); | 254 DISALLOW_COPY_AND_ASSIGN(DecoderTester); |
| 198 }; | 255 }; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 398 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
| 342 kTestRects, 1); | 399 kTestRects, 1); |
| 343 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 400 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
| 344 kTestRects + 1, 1); | 401 kTestRects + 1, 1); |
| 345 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 402 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
| 346 kTestRects + 2, 1); | 403 kTestRects + 2, 1); |
| 347 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 404 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
| 348 kTestRects + 3, 2); | 405 kTestRects + 3, 2); |
| 349 } | 406 } |
| 350 | 407 |
| 408 static void FillWithGradient(uint8* memory, const SkISize& frame_size, |
| 409 const SkIRect& rect) { |
| 410 for (int j = rect.top(); j < rect.bottom(); ++j) { |
| 411 uint8* p = memory + ((j * frame_size.width()) + rect.left()) * 4; |
| 412 for (int i = rect.left(); i < rect.right(); ++i) { |
| 413 *p++ = static_cast<uint8>((255.0 * i) / frame_size.width()); |
| 414 *p++ = static_cast<uint8>((164.0 * j) / frame_size.height()); |
| 415 *p++ = static_cast<uint8>((82.0 * (i + j)) / |
| 416 (frame_size.width() + frame_size.height())); |
| 417 *p++ = 0; |
| 418 } |
| 419 } |
| 420 } |
| 421 |
| 422 void TestEncoderDecoderGradient(Encoder* encoder, |
| 423 Decoder* decoder, |
| 424 double max_error_limit, |
| 425 double mean_error_limit) { |
| 426 SkIRect full_frame = SkIRect::MakeWH(kWidth, kHeight); |
| 427 scoped_array<uint8> frame_data(new uint8[kWidth * kHeight * kBytesPerPixel]); |
| 428 FillWithGradient(frame_data.get(), SkISize::Make(kWidth, kHeight), |
| 429 full_frame); |
| 430 |
| 431 DataPlanes planes; |
| 432 memset(planes.data, 0, sizeof(planes.data)); |
| 433 memset(planes.strides, 0, sizeof(planes.strides)); |
| 434 planes.data[0] = frame_data.get(); |
| 435 planes.strides[0] = kWidth * kBytesPerPixel; |
| 436 |
| 437 scoped_refptr<CaptureData> capture_data = |
| 438 new CaptureData(planes, SkISize::Make(kWidth, kHeight), |
| 439 media::VideoFrame::RGB32); |
| 440 capture_data->mutable_dirty_region().op(full_frame, SkRegion::kUnion_Op); |
| 441 |
| 442 DecoderTester decoder_tester(decoder); |
| 443 decoder_tester.set_capture_data(capture_data); |
| 444 decoder_tester.AddRegion(capture_data->dirty_region()); |
| 445 |
| 446 encoder->Encode(capture_data, true, |
| 447 base::Bind(&DecoderTester::ReceivedScopedPacket, |
| 448 base::Unretained(&decoder_tester))); |
| 449 |
| 450 decoder_tester.VerifyResultsApprox(max_error_limit, mean_error_limit); |
| 451 } |
| 452 |
| 351 } // namespace remoting | 453 } // namespace remoting |
| OLD | NEW |