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.
4
5 #include <vector>
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "media/base/video_frame.h"
11 #include "media/cast/cast_defines.h"
12 #include "media/cast/cast_environment.h"
13 #include "media/cast/sender/video_encoder_impl.h"
14 #include "media/cast/test/fake_single_thread_task_runner.h"
15 #include "media/cast/test/utility/default_config.h"
16 #include "media/cast/test/utility/video_utility.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18
19 namespace media {
20 namespace cast {
21
22 using testing::_;
23
24 namespace {
25 class TestVideoEncoderCallback
26 : public base::RefCountedThreadSafe<TestVideoEncoderCallback> {
27 public:
TestVideoEncoderCallback(bool multiple_buffer_mode)28 explicit TestVideoEncoderCallback(bool multiple_buffer_mode)
29 : multiple_buffer_mode_(multiple_buffer_mode),
30 count_frames_delivered_(0) {}
31
count_frames_delivered() const32 int count_frames_delivered() const {
33 return count_frames_delivered_;
34 }
35
SetExpectedResult(uint32 expected_frame_id,uint32 expected_last_referenced_frame_id,const base::TimeTicks & expected_capture_time)36 void SetExpectedResult(uint32 expected_frame_id,
37 uint32 expected_last_referenced_frame_id,
38 const base::TimeTicks& expected_capture_time) {
39 expected_frame_id_ = expected_frame_id;
40 expected_last_referenced_frame_id_ = expected_last_referenced_frame_id;
41 expected_capture_time_ = expected_capture_time;
42 }
43
DeliverEncodedVideoFrame(scoped_ptr<EncodedFrame> encoded_frame)44 void DeliverEncodedVideoFrame(
45 scoped_ptr<EncodedFrame> encoded_frame) {
46 if (expected_frame_id_ != expected_last_referenced_frame_id_) {
47 EXPECT_EQ(EncodedFrame::DEPENDENT, encoded_frame->dependency);
48 } else if (!multiple_buffer_mode_) {
49 EXPECT_EQ(EncodedFrame::KEY, encoded_frame->dependency);
50 }
51 EXPECT_EQ(expected_frame_id_, encoded_frame->frame_id);
52 EXPECT_EQ(expected_last_referenced_frame_id_,
53 encoded_frame->referenced_frame_id)
54 << "frame id: " << expected_frame_id_;
55 EXPECT_LT(0u, encoded_frame->rtp_timestamp);
56 EXPECT_EQ(expected_capture_time_, encoded_frame->reference_time);
57 EXPECT_FALSE(encoded_frame->data.empty());
58 ++count_frames_delivered_;
59 }
60
61 private:
62 friend class base::RefCountedThreadSafe<TestVideoEncoderCallback>;
~TestVideoEncoderCallback()63 virtual ~TestVideoEncoderCallback() {}
64
65 const bool multiple_buffer_mode_;
66 int count_frames_delivered_;
67
68 uint32 expected_frame_id_;
69 uint32 expected_last_referenced_frame_id_;
70 base::TimeTicks expected_capture_time_;
71
72 DISALLOW_COPY_AND_ASSIGN(TestVideoEncoderCallback);
73 };
74 } // namespace
75
76 class VideoEncoderImplTest : public ::testing::Test {
77 protected:
VideoEncoderImplTest()78 VideoEncoderImplTest() {
79 video_config_ = GetDefaultVideoSenderConfig();
80 video_config_.codec = CODEC_VIDEO_VP8;
81 gfx::Size size(video_config_.width, video_config_.height);
82 video_frame_ = media::VideoFrame::CreateFrame(
83 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta());
84 PopulateVideoFrame(video_frame_.get(), 123);
85 }
86
~VideoEncoderImplTest()87 virtual ~VideoEncoderImplTest() {}
88
SetUp()89 virtual void SetUp() OVERRIDE {
90 testing_clock_ = new base::SimpleTestTickClock();
91 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
92 task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_);
93 cast_environment_ =
94 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
95 task_runner_,
96 task_runner_,
97 task_runner_);
98 }
99
TearDown()100 virtual void TearDown() OVERRIDE {
101 video_encoder_.reset();
102 task_runner_->RunTasks();
103 }
104
CreateEncoder()105 void CreateEncoder() {
106 test_video_encoder_callback_ = new TestVideoEncoderCallback(
107 video_config_.max_number_of_video_buffers_used != 1);
108 video_encoder_.reset(new VideoEncoderImpl(
109 cast_environment_, video_config_,
110 0 /* useless arg to be removed in later change */));
111 }
112
113 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
114 scoped_refptr<TestVideoEncoderCallback> test_video_encoder_callback_;
115 VideoSenderConfig video_config_;
116 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
117 scoped_ptr<VideoEncoder> video_encoder_;
118 scoped_refptr<media::VideoFrame> video_frame_;
119
120 scoped_refptr<CastEnvironment> cast_environment_;
121
122 DISALLOW_COPY_AND_ASSIGN(VideoEncoderImplTest);
123 };
124
TEST_F(VideoEncoderImplTest,GeneratesKeyFrameThenOnlyDeltaFrames)125 TEST_F(VideoEncoderImplTest, GeneratesKeyFrameThenOnlyDeltaFrames) {
126 CreateEncoder();
127
128 VideoEncoder::FrameEncodedCallback frame_encoded_callback =
129 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame,
130 test_video_encoder_callback_.get());
131
132 EXPECT_EQ(0, test_video_encoder_callback_->count_frames_delivered());
133
134 test_video_encoder_callback_->SetExpectedResult(
135 0, 0, testing_clock_->NowTicks());
136 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
137 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
138 task_runner_->RunTasks();
139
140 for (uint32 frame_id = 1; frame_id < 10; ++frame_id) {
141 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33));
142 test_video_encoder_callback_->SetExpectedResult(
143 frame_id, frame_id - 1, testing_clock_->NowTicks());
144 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
145 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
146 task_runner_->RunTasks();
147 }
148
149 EXPECT_EQ(10, test_video_encoder_callback_->count_frames_delivered());
150 }
151
TEST_F(VideoEncoderImplTest,FramesDoNotDependOnUnackedFramesInMultiBufferMode)152 TEST_F(VideoEncoderImplTest,
153 FramesDoNotDependOnUnackedFramesInMultiBufferMode) {
154 video_config_.max_number_of_video_buffers_used = 3;
155 CreateEncoder();
156
157 VideoEncoder::FrameEncodedCallback frame_encoded_callback =
158 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame,
159 test_video_encoder_callback_.get());
160
161 EXPECT_EQ(0, test_video_encoder_callback_->count_frames_delivered());
162
163 test_video_encoder_callback_->SetExpectedResult(
164 0, 0, testing_clock_->NowTicks());
165 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
166 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
167 task_runner_->RunTasks();
168
169 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33));
170 video_encoder_->LatestFrameIdToReference(0);
171 test_video_encoder_callback_->SetExpectedResult(
172 1, 0, testing_clock_->NowTicks());
173 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
174 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
175 task_runner_->RunTasks();
176
177 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33));
178 video_encoder_->LatestFrameIdToReference(1);
179 test_video_encoder_callback_->SetExpectedResult(
180 2, 1, testing_clock_->NowTicks());
181 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
182 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
183 task_runner_->RunTasks();
184
185 video_encoder_->LatestFrameIdToReference(2);
186
187 for (uint32 frame_id = 3; frame_id < 10; ++frame_id) {
188 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33));
189 test_video_encoder_callback_->SetExpectedResult(
190 frame_id, 2, testing_clock_->NowTicks());
191 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(
192 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback));
193 task_runner_->RunTasks();
194 }
195
196 EXPECT_EQ(10, test_video_encoder_callback_->count_frames_delivered());
197 }
198
199 } // namespace cast
200 } // namespace media
201