Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / remoting / host / video_frame_recorder_unittest.cc
blobf0f5b9d440295ebe534cb6cb9a7145be5f8e6960
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/host/video_frame_recorder.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/stl_util.h"
10 #include "remoting/codec/video_encoder_verbatim.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
13 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
16 namespace webrtc {
18 // Define equality operator for DesktopFrame to allow use of EXPECT_EQ().
19 static bool operator==(const DesktopFrame& a,
20 const DesktopFrame& b) {
21 if ((a.size().equals(b.size())) &&
22 (a.updated_region().Equals(b.updated_region())) &&
23 (a.dpi().equals(b.dpi()))) {
24 for (int i = 0; i < a.size().height(); ++i) {
25 if (memcmp(a.data() + a.stride() * i,
26 b.data() + b.stride() * i,
27 a.size().width() * DesktopFrame::kBytesPerPixel) != 0) {
28 return false;
31 return true;
33 return false;
36 } // namespace
38 namespace remoting {
40 const int64_t kMaxContentBytes = 10 * 1024 * 1024;
41 const int kWidth = 640;
42 const int kHeight = 480;
43 const int kTestFrameCount = 6;
45 class VideoFrameRecorderTest : public testing::Test {
46 public:
47 VideoFrameRecorderTest();
49 virtual void SetUp() OVERRIDE;
50 virtual void TearDown() OVERRIDE;
52 void CreateAndWrapEncoder();
53 scoped_ptr<webrtc::DesktopFrame> CreateNextFrame();
54 void CreateTestFrames();
55 void EncodeTestFrames();
56 void EncodeDummyFrame();
57 void StartRecording();
58 void VerifyTestFrames();
60 protected:
61 base::MessageLoop message_loop_;
63 scoped_ptr<VideoFrameRecorder> recorder_;
64 scoped_ptr<VideoEncoder> encoder_;
66 std::list<webrtc::DesktopFrame*> test_frames_;
67 int frame_count_;
70 VideoFrameRecorderTest::VideoFrameRecorderTest() : frame_count_(0) {}
72 void VideoFrameRecorderTest::SetUp() {
73 recorder_.reset(new VideoFrameRecorder());
74 recorder_->SetMaxContentBytes(kMaxContentBytes);
77 void VideoFrameRecorderTest::TearDown() {
78 ASSERT_TRUE(test_frames_.empty());
80 // Allow events posted to the recorder_, if still valid, to be processed.
81 base::RunLoop().RunUntilIdle();
83 // Tear down the recorder, if necessary.
84 recorder_.reset();
86 // Process any events resulting from recorder teardown.
87 base::RunLoop().RunUntilIdle();
90 void VideoFrameRecorderTest::CreateAndWrapEncoder() {
91 scoped_ptr<VideoEncoder> encoder(new VideoEncoderVerbatim());
92 encoder_ = recorder_->WrapVideoEncoder(encoder.Pass());
94 // Encode a dummy frame to bind the wrapper to the TaskRunner.
95 EncodeDummyFrame();
98 scoped_ptr<webrtc::DesktopFrame> VideoFrameRecorderTest::CreateNextFrame() {
99 scoped_ptr<webrtc::DesktopFrame> frame(
100 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight)));
102 // Fill content, DPI and updated-region based on |frame_count_| so that each
103 // generated frame is different.
104 memset(frame->data(), frame_count_, frame->stride() * kHeight);
105 frame->set_dpi(webrtc::DesktopVector(frame_count_, frame_count_));
106 frame->mutable_updated_region()->SetRect(
107 webrtc::DesktopRect::MakeWH(frame_count_, frame_count_));
108 ++frame_count_;
110 return frame.Pass();
113 void VideoFrameRecorderTest::CreateTestFrames() {
114 for (int i=0; i < kTestFrameCount; ++i) {
115 test_frames_.push_back(CreateNextFrame().release());
119 void VideoFrameRecorderTest::EncodeTestFrames() {
120 std::list<webrtc::DesktopFrame*>::iterator i;
121 for (i = test_frames_.begin(); i != test_frames_.end(); ++i) {
122 scoped_ptr<VideoPacket> packet = encoder_->Encode(*(*i));
124 // Process tasks to let the recorder pick up the frame.
125 base::RunLoop().RunUntilIdle();
129 void VideoFrameRecorderTest::EncodeDummyFrame() {
130 webrtc::BasicDesktopFrame dummy_frame(webrtc::DesktopSize(kWidth, kHeight));
131 scoped_ptr<VideoPacket> packet = encoder_->Encode(dummy_frame);
132 base::RunLoop().RunUntilIdle();
135 void VideoFrameRecorderTest::StartRecording() {
136 // Start the recorder and pump events to let things initialize.
137 recorder_->SetEnableRecording(true);
138 base::RunLoop().RunUntilIdle();
141 void VideoFrameRecorderTest::VerifyTestFrames() {
142 // Verify that the recorded frames match the ones passed to the encoder.
143 while (!test_frames_.empty()) {
144 scoped_ptr<webrtc::DesktopFrame> recorded_frame(recorder_->NextFrame());
145 ASSERT_TRUE(recorded_frame);
147 scoped_ptr<webrtc::DesktopFrame> expected_frame(test_frames_.front());
148 test_frames_.pop_front();
150 EXPECT_EQ(*recorded_frame, *expected_frame);
153 EXPECT_FALSE(recorder_->NextFrame());
156 // Basic test that creating & tearing down VideoFrameRecorder doesn't crash.
157 TEST_F(VideoFrameRecorderTest, CreateDestroy) {
160 // Basic test that creating, starting, stopping and destroying a
161 // VideoFrameRecorder don't end the world.
162 TEST_F(VideoFrameRecorderTest, StartStop) {
163 StartRecording();
164 recorder_->SetEnableRecording(false);
167 // Test that tearing down the VideoFrameRecorder while the VideoEncoder
168 // wrapper exists doesn't crash.
169 TEST_F(VideoFrameRecorderTest, DestroyVideoFrameRecorderFirst) {
170 CreateAndWrapEncoder();
172 // Start the recorder, so that the wrapper will push frames to it.
173 StartRecording();
175 // Tear down the recorder.
176 recorder_.reset();
178 // Encode a dummy frame via the wrapper to ensure we don't crash.
179 EncodeDummyFrame();
182 // Test that creating & tearing down the wrapper while the
183 // VideoFrameRecorder still exists doesn't crash.
184 TEST_F(VideoFrameRecorderTest, DestroyVideoEncoderWrapperFirst) {
185 CreateAndWrapEncoder();
187 // Start the recorder, so that the wrapper will push frames to it.
188 StartRecording();
190 // Encode a dummy frame via the wrapper to ensure we don't crash.
191 EncodeDummyFrame();
193 // Tear down the encoder wrapper.
194 encoder_.reset();
196 // Test teardown will stop the recorder and process pending events.
199 // Test that when asked to encode a short sequence of frames, those frames are
200 // all recorded, in sequence.
201 TEST_F(VideoFrameRecorderTest, RecordFrames) {
202 CreateAndWrapEncoder();
204 // Start the recorder, so that the wrapper will push frames to it.
205 StartRecording();
207 // Create frames, store them and pass them to the encoder.
208 CreateTestFrames();
209 EncodeTestFrames();
211 // Verify that the recorded frames match the ones passed to the encoder.
212 VerifyTestFrames();
215 // Test that when asked to record more frames than the maximum content bytes
216 // limit allows, the first encoded frames are dropped.
217 TEST_F(VideoFrameRecorderTest, MaxContentBytesEnforced) {
218 CreateAndWrapEncoder();
220 // Configure a maximum content size sufficient for five and a half frames.
221 int64 frame_bytes = kWidth * kHeight * webrtc::DesktopFrame::kBytesPerPixel;
222 recorder_->SetMaxContentBytes((frame_bytes * 11) / 2);
224 // Start the recorder, so that the wrapper will push frames to it.
225 StartRecording();
227 // Create frames, store them and pass them to the encoder.
228 CreateTestFrames();
229 EncodeTestFrames();
231 // Only five of the supplied frames should have been recorded.
232 while (test_frames_.size() > 5) {
233 scoped_ptr<webrtc::DesktopFrame> frame(test_frames_.front());
234 test_frames_.pop_front();
237 // Verify that the recorded frames match the ones passed to the encoder.
238 VerifyTestFrames();
241 // Test that when asked to record more frames than the maximum content bytes
242 // limit allows, the first encoded frames are dropped.
243 TEST_F(VideoFrameRecorderTest, ContentBytesUpdatedByNextFrame) {
244 CreateAndWrapEncoder();
246 // Configure a maximum content size sufficient for kTestFrameCount frames.
247 int64 frame_bytes = kWidth * kHeight * webrtc::DesktopFrame::kBytesPerPixel;
248 recorder_->SetMaxContentBytes(frame_bytes * kTestFrameCount);
250 // Start the recorder, so that the wrapper will push frames to it.
251 StartRecording();
253 // Encode a frame, to record it, and consume it from the recorder.
254 EncodeDummyFrame();
255 scoped_ptr<webrtc::DesktopFrame> frame = recorder_->NextFrame();
256 EXPECT_TRUE(frame);
258 // Create frames, store them and pass them to the encoder.
259 CreateTestFrames();
260 EncodeTestFrames();
262 // Verify that the recorded frames match the ones passed to the encoder.
263 VerifyTestFrames();
266 // Test that when asked to encode a short sequence of frames, none are recorded
267 // if recording was not enabled.
268 TEST_F(VideoFrameRecorderTest, EncodeButDontRecord) {
269 CreateAndWrapEncoder();
271 // Create frames, store them and pass them to the encoder.
272 CreateTestFrames();
273 EncodeTestFrames();
275 // Clear the list of expected test frames, since none should be recorded.
276 STLDeleteElements(&test_frames_);
278 // Verify that the recorded frames match the ones passed to the encoder.
279 VerifyTestFrames();
282 } // namespace remoting