OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "remoting/codec/video_encoder_vpx.h" | 5 #include "remoting/codec/video_encoder_vpx.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "remoting/codec/codec_test.h" | 12 #include "remoting/codec/codec_test.h" |
12 #include "remoting/proto/video.pb.h" | 13 #include "remoting/proto/video.pb.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 15 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
15 | 16 |
17 using webrtc::BasicDesktopFrame; | |
18 using webrtc::DesktopFrame; | |
19 using webrtc::DesktopRect; | |
20 using webrtc::DesktopSize; | |
21 using webrtc::DesktopVector; | |
22 | |
16 namespace remoting { | 23 namespace remoting { |
17 | 24 |
18 // xRGB pixel colors for use by tests. | 25 // xRGB pixel colors for use by tests. |
19 const uint32 kBlueColor = 0x0000ff; | 26 const uint32 kBlueColor = 0x0000ff; |
20 const uint32 kGreenColor = 0x00ff00; | 27 const uint32 kGreenColor = 0x00ff00; |
21 | 28 |
22 // Creates a frame stippled between blue and red pixels, which is useful for | 29 // Creates a frame stippled between blue and red pixels, which is useful for |
23 // lossy/lossless encode and color tests. | 30 // lossy/lossless encode and color tests. |
24 static scoped_ptr<webrtc::DesktopFrame> CreateTestFrame( | 31 static scoped_ptr<DesktopFrame> CreateTestFrame( |
25 const webrtc::DesktopSize& frame_size) { | 32 const DesktopSize& frame_size) { |
26 scoped_ptr<webrtc::DesktopFrame> frame( | 33 scoped_ptr<DesktopFrame> frame( |
27 new webrtc::BasicDesktopFrame(frame_size)); | 34 new BasicDesktopFrame(frame_size)); |
28 for (int x = 0; x < frame_size.width(); ++x) { | 35 for (int x = 0; x < frame_size.width(); ++x) { |
29 for (int y = 0; y < frame_size.height(); ++y) { | 36 for (int y = 0; y < frame_size.height(); ++y) { |
30 uint8* pixel_u8 = frame->data() + (y * frame->stride()) + | 37 uint8* pixel_u8 = frame->data() + (y * frame->stride()) + |
31 (x * webrtc::DesktopFrame::kBytesPerPixel); | 38 (x * DesktopFrame::kBytesPerPixel); |
32 *(reinterpret_cast<uint32*>(pixel_u8)) = | 39 *(reinterpret_cast<uint32*>(pixel_u8)) = |
33 ((x + y) & 1) ? kGreenColor : kBlueColor; | 40 ((x + y) & 1) ? kGreenColor : kBlueColor; |
34 } | 41 } |
35 } | 42 } |
36 return frame.Pass(); | 43 return frame.Pass(); |
37 } | 44 } |
38 | 45 |
39 TEST(VideoEncoderVpxTest, TestVp8VideoEncoder) { | 46 TEST(VideoEncoderVpxTest, TestVp8VideoEncoder) { |
40 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); | 47 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); |
41 TestVideoEncoder(encoder.get(), false); | 48 TestVideoEncoder(encoder.get(), false); |
42 } | 49 } |
43 | 50 |
44 TEST(VideoEncoderVpxTest, TestVp9VideoEncoder) { | 51 TEST(VideoEncoderVpxTest, TestVp9VideoEncoder) { |
45 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); | 52 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); |
46 // VP9 encoder defaults to lossless encode and lossy (I420) color. | 53 // VP9 encoder defaults to lossless encode and lossy (I420) color. |
47 TestVideoEncoder(encoder.get(), false); | 54 TestVideoEncoder(encoder.get(), false); |
48 } | 55 } |
49 | 56 |
50 // Test that the VP9 encoder can switch between lossy & lossless encode. | 57 // Test that the VP9 encoder can switch between lossy & lossless encode. |
51 TEST(VideoEncoderVpxTest, TestVp9VideoEncoderLossyEncode) { | 58 TEST(VideoEncoderVpxTest, TestVp9VideoEncoderLossyEncode) { |
52 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); | 59 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); |
53 | 60 |
54 webrtc::DesktopSize frame_size(1024, 768); | 61 DesktopSize frame_size(1024, 768); |
55 scoped_ptr<webrtc::DesktopFrame> frame(CreateTestFrame(frame_size)); | 62 scoped_ptr<DesktopFrame> frame(CreateTestFrame(frame_size)); |
56 frame->mutable_updated_region()->SetRect( | 63 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(frame_size)); |
57 webrtc::DesktopRect::MakeSize(frame_size)); | |
58 | 64 |
59 // Lossy encode the first frame. | 65 // Lossy encode the first frame. |
60 encoder->SetLosslessEncode(false); | 66 encoder->SetLosslessEncode(false); |
61 scoped_ptr<VideoPacket> lossy_packet = encoder->Encode(*frame); | 67 scoped_ptr<VideoPacket> lossy_packet = encoder->Encode(*frame); |
62 | 68 |
63 // Lossless encode the second frame. | 69 // Lossless encode the second frame. |
64 encoder->SetLosslessEncode(true); | 70 encoder->SetLosslessEncode(true); |
65 scoped_ptr<VideoPacket> lossless_packet = encoder->Encode(*frame); | 71 scoped_ptr<VideoPacket> lossless_packet = encoder->Encode(*frame); |
66 EXPECT_GT(lossless_packet->data().size(), lossy_packet->data().size()); | 72 EXPECT_GT(lossless_packet->data().size(), lossy_packet->data().size()); |
67 | 73 |
68 // Lossy encode one more frame. | 74 // Lossy encode one more frame. |
69 encoder->SetLosslessEncode(false); | 75 encoder->SetLosslessEncode(false); |
70 lossy_packet = encoder->Encode(*frame); | 76 lossy_packet = encoder->Encode(*frame); |
71 EXPECT_LT(lossy_packet->data().size(), lossless_packet->data().size()); | 77 EXPECT_LT(lossy_packet->data().size(), lossless_packet->data().size()); |
72 } | 78 } |
73 | 79 |
74 // Test that the VP9 encoder can switch between lossy & lossless color. | 80 // Test that the VP9 encoder can switch between lossy & lossless color. |
75 TEST(VideoEncoderVpxTest, TestVp9VideoEncoderLossyColor) { | 81 TEST(VideoEncoderVpxTest, TestVp9VideoEncoderLossyColor) { |
76 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); | 82 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); |
77 | 83 |
78 webrtc::DesktopSize frame_size(1024, 768); | 84 DesktopSize frame_size(1024, 768); |
79 scoped_ptr<webrtc::DesktopFrame> frame(CreateTestFrame(frame_size)); | 85 scoped_ptr<DesktopFrame> frame(CreateTestFrame(frame_size)); |
80 frame->mutable_updated_region()->SetRect( | 86 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(frame_size)); |
81 webrtc::DesktopRect::MakeSize(frame_size)); | |
82 | 87 |
83 // Lossy encode the first frame. | 88 // Lossy encode the first frame. |
84 encoder->SetLosslessColor(false); | 89 encoder->SetLosslessColor(false); |
85 scoped_ptr<VideoPacket> lossy_packet = encoder->Encode(*frame); | 90 scoped_ptr<VideoPacket> lossy_packet = encoder->Encode(*frame); |
86 | 91 |
87 // Lossless encode the second frame. | 92 // Lossless encode the second frame. |
88 encoder->SetLosslessColor(true); | 93 encoder->SetLosslessColor(true); |
89 scoped_ptr<VideoPacket> lossless_packet = encoder->Encode(*frame); | 94 scoped_ptr<VideoPacket> lossless_packet = encoder->Encode(*frame); |
90 EXPECT_GT(lossless_packet->data().size(), lossy_packet->data().size()); | 95 EXPECT_GT(lossless_packet->data().size(), lossy_packet->data().size()); |
91 | 96 |
92 // Lossy encode one more frame. | 97 // Lossy encode one more frame. |
93 encoder->SetLosslessColor(false); | 98 encoder->SetLosslessColor(false); |
94 lossy_packet = encoder->Encode(*frame); | 99 lossy_packet = encoder->Encode(*frame); |
95 EXPECT_LT(lossy_packet->data().size(), lossless_packet->data().size()); | 100 EXPECT_LT(lossy_packet->data().size(), lossless_packet->data().size()); |
96 } | 101 } |
97 | 102 |
98 // Test that the VP8 encoder ignores lossless modes without crashing. | 103 // Test that the VP8 encoder ignores lossless modes without crashing. |
99 TEST(VideoEncoderVpxTest, TestVp8VideoEncoderIgnoreLossy) { | 104 TEST(VideoEncoderVpxTest, TestVp8VideoEncoderIgnoreLossy) { |
100 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); | 105 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); |
101 | 106 |
102 webrtc::DesktopSize frame_size(1024, 768); | 107 DesktopSize frame_size(1024, 768); |
103 scoped_ptr<webrtc::DesktopFrame> frame(CreateTestFrame(frame_size)); | 108 scoped_ptr<DesktopFrame> frame(CreateTestFrame(frame_size)); |
104 frame->mutable_updated_region()->SetRect( | 109 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(frame_size)); |
105 webrtc::DesktopRect::MakeSize(frame_size)); | |
106 | 110 |
107 // Encode a frame, to give the encoder a chance to crash if misconfigured. | 111 // Encode a frame, to give the encoder a chance to crash if misconfigured. |
108 encoder->SetLosslessEncode(true); | 112 encoder->SetLosslessEncode(true); |
109 encoder->SetLosslessColor(true); | 113 encoder->SetLosslessColor(true); |
110 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); | 114 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); |
111 EXPECT_TRUE(packet); | 115 EXPECT_TRUE(packet); |
112 } | 116 } |
113 | 117 |
114 // Test that calling Encode with a differently-sized media::ScreenCaptureData | 118 // Test that calling Encode with a differently-sized media::ScreenCaptureData |
115 // does not leak memory. | 119 // does not leak memory. |
116 TEST(VideoEncoderVpxTest, TestSizeChangeNoLeak) { | 120 TEST(VideoEncoderVpxTest, TestSizeChangeNoLeak) { |
117 webrtc::DesktopSize frame_size(1000, 1000); | 121 DesktopSize frame_size(1000, 1000); |
118 | 122 |
119 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); | 123 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); |
120 | 124 |
121 // Create first frame & encode it. | 125 // Create first frame & encode it. |
122 scoped_ptr<webrtc::DesktopFrame> frame(CreateTestFrame(frame_size)); | 126 scoped_ptr<DesktopFrame> frame(CreateTestFrame(frame_size)); |
123 frame->mutable_updated_region()->SetRect( | 127 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(frame_size)); |
124 webrtc::DesktopRect::MakeSize(frame_size)); | |
125 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); | 128 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); |
126 EXPECT_TRUE(packet); | 129 EXPECT_TRUE(packet); |
127 | 130 |
128 // Halve the size of the frame, and updated region, and encode again. | 131 // Halve the size of the frame, and updated region, and encode again. |
129 frame_size.set(frame_size.width(), frame_size.height() / 2); | 132 frame_size.set(frame_size.width(), frame_size.height() / 2); |
130 frame = CreateTestFrame(frame_size); | 133 frame = CreateTestFrame(frame_size); |
131 frame->mutable_updated_region()->SetRect( | 134 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(frame_size)); |
132 webrtc::DesktopRect::MakeSize(frame_size)); | |
133 packet = encoder->Encode(*frame); | 135 packet = encoder->Encode(*frame); |
134 EXPECT_TRUE(packet); | 136 EXPECT_TRUE(packet); |
135 } | 137 } |
136 | 138 |
137 // Test that the DPI information is correctly propagated from the | 139 // Test that the DPI information is correctly propagated from the |
138 // media::ScreenCaptureData to the VideoPacket. | 140 // media::ScreenCaptureData to the VideoPacket. |
139 TEST(VideoEncoderVpxTest, TestDpiPropagation) { | 141 TEST(VideoEncoderVpxTest, TestDpiPropagation) { |
140 webrtc::DesktopSize frame_size(32, 32); | 142 DesktopSize frame_size(32, 32); |
141 | 143 |
142 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); | 144 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); |
143 | 145 |
144 scoped_ptr<webrtc::DesktopFrame> frame(CreateTestFrame(frame_size)); | 146 scoped_ptr<DesktopFrame> frame(CreateTestFrame(frame_size)); |
145 frame->set_dpi(webrtc::DesktopVector(96, 97)); | 147 frame->set_dpi(DesktopVector(96, 97)); |
146 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); | 148 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); |
147 EXPECT_EQ(packet->format().x_dpi(), 96); | 149 EXPECT_EQ(packet->format().x_dpi(), 96); |
148 EXPECT_EQ(packet->format().y_dpi(), 97); | 150 EXPECT_EQ(packet->format().y_dpi(), 97); |
149 } | 151 } |
150 | 152 |
153 // Measure the performance of the VP8 encoder. | |
154 TEST(VideoEncoderVpxTest, MANUAL_MeasureVp8Fps) { | |
155 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); | |
156 | |
157 const DesktopSize kFrameSizes[] = { | |
158 DesktopSize(1280, 1024), DesktopSize(1920, 1200) | |
159 }; | |
160 | |
161 for (size_t i = 0; i < arraysize(kFrameSizes); ++i) { | |
162 float fps = | |
163 MeasureVideoEncoderFpsWithSize(encoder.get(), kFrameSizes[i]); | |
164 LOG(ERROR) << kFrameSizes[i].width() << "x" << kFrameSizes[i].height() | |
165 << ": " << fps << "fps"; | |
166 } | |
167 } | |
168 | |
169 // Measure the performance of the VP9 encoder. | |
170 TEST(VideoEncoderVpxTest, MANUAL_MeasureVp9Fps) { | |
171 const DesktopSize kFrameSizes[] = { | |
172 DesktopSize(1280, 1024), DesktopSize(1920, 1200) | |
173 }; | |
174 | |
175 for (int lossless_mode = 0; lossless_mode < 4; ++lossless_mode) { | |
Sergey Ulanov
2014/06/24 02:00:51
nit: it might be more readable have list of tests
Wez
2014/06/24 02:14:13
I prefer to iterate over sizes and iterate over lo
| |
176 bool lossless_color = lossless_mode & 1; | |
177 bool lossless_encode = lossless_mode & 2; | |
178 | |
179 scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); | |
180 encoder->SetLosslessColor(lossless_color); | |
181 encoder->SetLosslessEncode(lossless_encode); | |
182 | |
183 for (size_t i = 0; i < arraysize(kFrameSizes); ++i) { | |
184 float fps = | |
185 MeasureVideoEncoderFpsWithSize(encoder.get(), kFrameSizes[i]); | |
186 LOG(ERROR) << kFrameSizes[i].width() << "x" << kFrameSizes[i].height() | |
187 << "(" << (lossless_encode ? "lossless" : "lossy ") << ")" | |
188 << "(" << (lossless_color ? "I444" : "I420") << ")" | |
189 << ": " << fps << "fps"; | |
190 } | |
191 } | |
192 } | |
193 | |
151 } // namespace remoting | 194 } // namespace remoting |
OLD | NEW |