Chromium Code Reviews| Index: remoting/base/codec_test.cc |
| diff --git a/remoting/base/codec_test.cc b/remoting/base/codec_test.cc |
| index 381fdf4a3f2a3727b1607445c83c28651cd14301..d323a39e0a974550594787bc05e55a0fd1119ab0 100644 |
| --- a/remoting/base/codec_test.cc |
| +++ b/remoting/base/codec_test.cc |
| @@ -147,6 +147,10 @@ class DecoderTester { |
| } |
| } |
| + void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
| + ReceivedPacket(packet.get()); |
| + } |
| + |
| void set_strict(bool strict) { |
| strict_ = strict; |
| } |
| @@ -158,7 +162,11 @@ class DecoderTester { |
| void AddRects(const SkIRect* rects, int count) { |
| SkRegion new_rects; |
| new_rects.setRects(rects, count); |
| - expected_region_.op(new_rects, SkRegion::kUnion_Op); |
| + AddRegion(new_rects); |
| + } |
| + |
| + void AddRegion(const SkRegion& region) { |
| + expected_region_.op(region, SkRegion::kUnion_Op); |
| } |
| void VerifyResults() { |
| @@ -186,6 +194,41 @@ class DecoderTester { |
| } |
| } |
| + void VerifyResultsApprox(double max_error_limit, double mean_error_limit) { |
| + ASSERT_TRUE(capture_data_.get()); |
| + |
| + // Test the content of the update region. |
| + EXPECT_EQ(expected_region_, update_region_); |
| + double max_error = 0.0; |
| + double sum_error = 0.0; |
| + int error_num = 0; |
| + for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
| + const int stride = kWidth * kBytesPerPixel; |
| + EXPECT_EQ(stride, capture_data_->data_planes().strides[0]); |
| + const int offset = stride * i.rect().top() + |
| + kBytesPerPixel * i.rect().left(); |
| + const uint8* original = capture_data_->data_planes().data[0] + offset; |
| + const uint8* decoded = image_data_.get() + offset; |
| + for (int y = 0; y < i.rect().height(); ++y) { |
| + for (int x = 0; x < i.rect().width(); ++x) { |
| + for (int i = 0; i < 3; i++) { |
| + UpdateErrorMetrics(original, decoded, max_error, sum_error, |
|
Sergey Ulanov
2012/07/26 04:00:17
PSNR is a standard metric that is used to measure
|
| + error_num); |
| + original++; |
| + decoded++; |
| + } |
| + original++; |
| + decoded++; |
| + } |
| + } |
| + } |
| + EXPECT_LE(max_error, max_error_limit); |
| + double mean_error = sum_error / error_num; |
| + EXPECT_LE(mean_error, mean_error_limit); |
| + LOG(INFO) << "Max error: " << max_error; |
| + LOG(INFO) << "Mean error: " << mean_error; |
| + } |
| + |
| private: |
| bool strict_; |
| SkRegion expected_region_; |
| @@ -194,6 +237,16 @@ class DecoderTester { |
| scoped_array<uint8> image_data_; |
| scoped_refptr<CaptureData> capture_data_; |
| + void UpdateErrorMetrics(const uint8* p1, const uint8* p2, |
| + double& max_error, double& sum_error, |
| + int& error_num) { |
| + double error = |
| + std::abs(static_cast<int>(*p1) - static_cast<int>(*p2)) / 255.0; |
| + max_error = std::max(max_error, error); |
| + sum_error += error; |
| + error_num++; |
| + } |
| + |
| DISALLOW_COPY_AND_ASSIGN(DecoderTester); |
| }; |
| @@ -348,4 +401,48 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { |
| kTestRects + 3, 2); |
| } |
| +static void FillWithGradient(uint8* memory, const SkISize& frame_size, |
| + const SkIRect& rect) { |
| + for (int j = rect.top(); j < rect.bottom(); ++j) { |
| + for (int i = rect.left(); i < rect.right(); ++i) { |
| + uint8* p = memory + ((j * frame_size.width()) + i) * 4; |
| + *p++ = static_cast<uint8>((255.0 * i) / frame_size.width()); |
| + *p++ = static_cast<uint8>((164.0 * j) / frame_size.height()); |
| + *p++ = static_cast<uint8>((82.0 * (i + j)) / |
| + (frame_size.width() + frame_size.height())); |
| + *p++ = 0; |
| + } |
| + } |
| +} |
| + |
| +void TestEncoderDecoderGradient(Encoder* encoder, Decoder* decoder, |
| + double max_error_limit, |
| + double mean_error_limit) { |
| + SkIRect full_frame = SkIRect::MakeWH(kWidth, kHeight); |
| + scoped_array<uint8> frame_data(new uint8[kWidth * kHeight * kBytesPerPixel]); |
| + FillWithGradient(frame_data.get(), SkISize::Make(kWidth, kHeight), |
| + full_frame); |
| + |
| + DataPlanes planes; |
| + memset(planes.data, 0, sizeof(planes.data)); |
| + memset(planes.strides, 0, sizeof(planes.strides)); |
| + planes.data[0] = frame_data.get(); |
| + planes.strides[0] = kWidth * kBytesPerPixel; |
| + |
| + scoped_refptr<CaptureData> capture_data = |
| + new CaptureData(planes, SkISize::Make(kWidth, kHeight), |
| + media::VideoFrame::RGB32); |
| + capture_data->mutable_dirty_region().op(full_frame, SkRegion::kUnion_Op); |
| + |
| + DecoderTester decoder_tester(decoder); |
| + decoder_tester.set_capture_data(capture_data); |
| + decoder_tester.AddRegion(capture_data->dirty_region()); |
| + |
| + encoder->Encode(capture_data, true, |
| + base::Bind(&DecoderTester::ReceivedScopedPacket, |
| + base::Unretained(&decoder_tester))); |
| + |
| + decoder_tester.VerifyResultsApprox(max_error_limit, mean_error_limit); |
| +} |
| + |
| } // namespace remoting |