Index: remoting/base/codec_test.cc |
diff --git a/remoting/base/codec_test.cc b/remoting/base/codec_test.cc |
index 5a67ba05d55cf8a425e56464d08dc201cce0bc8a..6813c66fc736c59e36ed4eb4d702db6a464e977f 100644 |
--- a/remoting/base/codec_test.cc |
+++ b/remoting/base/codec_test.cc |
@@ -16,18 +16,31 @@ |
#include "remoting/base/util.h" |
#include "testing/gtest/include/gtest/gtest.h" |
-static const int kWidth = 320; |
-static const int kHeight = 240; |
-static const int kBytesPerPixel = 4; |
+namespace { |
+ |
+const int kBytesPerPixel = 4; |
// Some sample rects for testing. |
-static const SkIRect kTestRects[] = { |
- SkIRect::MakeXYWH(0, 0, kWidth, kHeight), |
- SkIRect::MakeXYWH(0, 0, kWidth / 2, kHeight / 2), |
- SkIRect::MakeXYWH(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), |
- SkIRect::MakeXYWH(16, 16, 16, 16), |
- SkIRect::MakeXYWH(128, 64, 32, 32), |
-}; |
+std::vector<std::vector<SkIRect> > MakeTestRectLists(const SkISize& size) { |
+ std::vector<std::vector<SkIRect> > rect_lists; |
+ std::vector<SkIRect> rects; |
+ rects.push_back(SkIRect::MakeXYWH(0, 0, size.width(), size.height())); |
+ rect_lists.push_back(rects); |
+ rects.clear(); |
+ rects.push_back(SkIRect::MakeXYWH(0, 0, size.width() / 2, size.height() / 2)); |
+ rect_lists.push_back(rects); |
+ rects.clear(); |
+ rects.push_back(SkIRect::MakeXYWH(size.width() / 2, size.height() / 2, |
+ size.width() / 2, size.height() / 2)); |
+ rect_lists.push_back(rects); |
+ rects.clear(); |
+ rects.push_back(SkIRect::MakeXYWH(16, 16, 16, 16)); |
+ rects.push_back(SkIRect::MakeXYWH(128, 64, 32, 32)); |
+ rect_lists.push_back(rects); |
+ return rect_lists; |
+} |
+ |
+} // namespace |
namespace remoting { |
@@ -120,12 +133,16 @@ class EncoderMessageTester { |
class DecoderTester { |
public: |
- DecoderTester(Decoder* decoder) |
- : strict_(false), |
+ DecoderTester(Decoder* decoder, const SkISize& screen_size, |
+ const SkISize& view_size) |
+ : screen_size_(screen_size), |
+ view_size_(view_size), |
+ strict_(false), |
decoder_(decoder) { |
- image_data_.reset(new uint8[kWidth * kHeight * kBytesPerPixel]); |
+ image_data_.reset(new uint8[ |
+ view_size_.width() * view_size_.height() * kBytesPerPixel]); |
EXPECT_TRUE(image_data_.get()); |
- decoder_->Initialize(SkISize::Make(kWidth, kHeight)); |
+ decoder_->Initialize(screen_size_); |
} |
void Reset() { |
@@ -133,20 +150,29 @@ class DecoderTester { |
update_region_.setEmpty(); |
} |
+ void ResetRenderedData() { |
+ memset(image_data_.get(), 0, |
+ view_size_.width() * view_size_.height() * kBytesPerPixel); |
+ } |
+ |
void ReceivedPacket(VideoPacket* packet) { |
Decoder::DecodeResult result = decoder_->DecodePacket(packet); |
ASSERT_NE(Decoder::DECODE_ERROR, result); |
if (result == Decoder::DECODE_DONE) { |
- decoder_->RenderFrame(SkISize::Make(kWidth, kHeight), |
- SkIRect::MakeXYWH(0, 0, kWidth, kHeight), |
- image_data_.get(), |
- kWidth * kBytesPerPixel, |
- &update_region_); |
+ RenderFrame(); |
} |
} |
+ void RenderFrame() { |
+ decoder_->RenderFrame(view_size_, |
+ SkIRect::MakeSize(view_size_), |
+ image_data_.get(), |
+ view_size_.width() * kBytesPerPixel, |
+ &update_region_); |
+ } |
+ |
void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
ReceivedPacket(packet.get()); |
} |
@@ -178,7 +204,7 @@ class DecoderTester { |
// Test the content of the update region. |
EXPECT_EQ(expected_region_, update_region_); |
for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
- const int stride = kWidth * kBytesPerPixel; |
+ const int stride = view_size_.width() * kBytesPerPixel; |
EXPECT_EQ(stride, capture_data_->data_planes().strides[0]); |
const int offset = stride * i.rect().top() + |
kBytesPerPixel * i.rect().left(); |
@@ -197,29 +223,25 @@ class DecoderTester { |
// The error at each pixel is the root mean square of the errors in |
// the R, G, and B components, each normalized to [0, 1]. This routine |
// checks that the maximum and mean pixel errors do not exceed given limits. |
- 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_); |
+void VerifyResultsApprox(const uint8* expected_view_data, |
+ double max_error_limit, double mean_error_limit) { |
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 stride = view_size_.width() * kBytesPerPixel; |
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; |
+ const uint8* expected = expected_view_data + offset; |
+ const uint8* actual = image_data_.get() + offset; |
for (int y = 0; y < i.rect().height(); ++y) { |
for (int x = 0; x < i.rect().width(); ++x) { |
- double error = CalculateError(original, decoded); |
+ double error = CalculateError(expected, actual); |
max_error = std::max(max_error, error); |
sum_error += error; |
++error_num; |
- original += 4; |
- decoded += 4; |
+ expected += 4; |
+ actual += 4; |
} |
} |
} |
@@ -244,6 +266,8 @@ class DecoderTester { |
} |
private: |
+ SkISize screen_size_; |
+ SkISize view_size_; |
bool strict_; |
SkRegion expected_region_; |
SkRegion update_region_; |
@@ -294,15 +318,16 @@ class EncoderTester { |
DISALLOW_COPY_AND_ASSIGN(EncoderTester); |
}; |
-scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format, |
+scoped_refptr<CaptureData> PrepareEncodeData(const SkISize& size, |
+ media::VideoFrame::Format format, |
uint8** memory) { |
// TODO(hclam): Support also YUV format. |
CHECK_EQ(format, media::VideoFrame::RGB32); |
- int size = kWidth * kHeight * kBytesPerPixel; |
+ int memory_size = size.width() * size.height() * kBytesPerPixel; |
- *memory = new uint8[size]; |
+ *memory = new uint8[memory_size]; |
srand(0); |
- for (int i = 0; i < size; ++i) { |
+ for (int i = 0; i < memory_size; ++i) { |
(*memory)[i] = rand() % 256; |
} |
@@ -310,10 +335,10 @@ scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format, |
memset(planes.data, 0, sizeof(planes.data)); |
memset(planes.strides, 0, sizeof(planes.strides)); |
planes.data[0] = *memory; |
- planes.strides[0] = kWidth * kBytesPerPixel; |
+ planes.strides[0] = size.width() * kBytesPerPixel; |
scoped_refptr<CaptureData> data = |
- new CaptureData(planes, SkISize::Make(kWidth, kHeight), format); |
+ new CaptureData(planes, size, format); |
return data; |
} |
@@ -332,6 +357,8 @@ static void TestEncodingRects(Encoder* encoder, |
} |
void TestEncoder(Encoder* encoder, bool strict) { |
+ SkISize kSize = SkISize::Make(320, 240); |
+ |
EncoderMessageTester message_tester; |
message_tester.set_strict(strict); |
@@ -339,13 +366,15 @@ void TestEncoder(Encoder* encoder, bool strict) { |
uint8* memory; |
scoped_refptr<CaptureData> data = |
- PrepareEncodeData(media::VideoFrame::RGB32, &memory); |
+ PrepareEncodeData(kSize, media::VideoFrame::RGB32, &memory); |
scoped_array<uint8> memory_wrapper(memory); |
- TestEncodingRects(encoder, &tester, data, kTestRects, 1); |
- TestEncodingRects(encoder, &tester, data, kTestRects + 1, 1); |
- TestEncodingRects(encoder, &tester, data, kTestRects + 2, 1); |
- TestEncodingRects(encoder, &tester, data, kTestRects + 3, 2); |
+ std::vector<std::vector<SkIRect> > test_rect_lists = MakeTestRectLists(kSize); |
+ for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
+ const std::vector<SkIRect>& test_rects = test_rect_lists[i]; |
+ TestEncodingRects(encoder, &tester, data, |
+ &test_rects[0], test_rects.size()); |
+ } |
} |
static void TestEncodeDecodeRects(Encoder* encoder, |
@@ -380,6 +409,8 @@ static void TestEncodeDecodeRects(Encoder* encoder, |
} |
void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { |
+ SkISize kSize = SkISize::Make(320, 240); |
+ |
EncoderMessageTester message_tester; |
message_tester.set_strict(strict); |
@@ -387,22 +418,20 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { |
uint8* memory; |
scoped_refptr<CaptureData> data = |
- PrepareEncodeData(media::VideoFrame::RGB32, &memory); |
+ PrepareEncodeData(kSize, media::VideoFrame::RGB32, &memory); |
scoped_array<uint8> memory_wrapper(memory); |
- DecoderTester decoder_tester(decoder); |
+ DecoderTester decoder_tester(decoder, kSize, kSize); |
decoder_tester.set_strict(strict); |
decoder_tester.set_capture_data(data); |
encoder_tester.set_decoder_tester(&decoder_tester); |
- TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
- kTestRects, 1); |
- TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
- kTestRects + 1, 1); |
- TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
- kTestRects + 2, 1); |
- TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
- kTestRects + 3, 2); |
+ std::vector<std::vector<SkIRect> > test_rect_lists = MakeTestRectLists(kSize); |
+ for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
+ const std::vector<SkIRect> test_rects = test_rect_lists[i]; |
+ TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, |
+ &test_rects[0], test_rects.size()); |
+ } |
} |
static void FillWithGradient(uint8* memory, const SkISize& frame_size, |
@@ -421,25 +450,31 @@ static void FillWithGradient(uint8* memory, const SkISize& frame_size, |
void TestEncoderDecoderGradient(Encoder* encoder, |
Decoder* decoder, |
+ const SkISize& screen_size, |
+ const SkISize& view_size, |
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); |
+ SkIRect screen_rect = SkIRect::MakeSize(screen_size); |
+ scoped_array<uint8> screen_data(new uint8[ |
+ screen_size.width() * screen_size.height() * kBytesPerPixel]); |
+ FillWithGradient(screen_data.get(), screen_size, screen_rect); |
+ |
+ SkIRect view_rect = SkIRect::MakeSize(view_size); |
+ scoped_array<uint8> expected_view_data(new uint8[ |
+ view_size.width() * view_size.height() * kBytesPerPixel]); |
+ FillWithGradient(expected_view_data.get(), view_size, view_rect); |
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; |
+ planes.data[0] = screen_data.get(); |
+ planes.strides[0] = screen_size.width() * 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); |
+ new CaptureData(planes, screen_size, media::VideoFrame::RGB32); |
+ capture_data->mutable_dirty_region().op(screen_rect, SkRegion::kUnion_Op); |
- DecoderTester decoder_tester(decoder); |
+ DecoderTester decoder_tester(decoder, screen_size, view_size); |
decoder_tester.set_capture_data(capture_data); |
decoder_tester.AddRegion(capture_data->dirty_region()); |
@@ -447,7 +482,16 @@ void TestEncoderDecoderGradient(Encoder* encoder, |
base::Bind(&DecoderTester::ReceivedScopedPacket, |
base::Unretained(&decoder_tester))); |
- decoder_tester.VerifyResultsApprox(max_error_limit, mean_error_limit); |
+ decoder_tester.VerifyResultsApprox(expected_view_data.get(), |
+ max_error_limit, mean_error_limit); |
+ |
+ // Check that the decoder correctly re-renders the frame if its client |
+ // invalidates the frame. |
+ decoder_tester.ResetRenderedData(); |
+ decoder->Invalidate(view_size, SkRegion(view_rect)); |
+ decoder_tester.RenderFrame(); |
+ decoder_tester.VerifyResultsApprox(expected_view_data.get(), |
+ max_error_limit, mean_error_limit); |
} |
} // namespace remoting |