1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/codecs/test/videoprocessor.h"
12
13 #include <memory>
14
15 #include "api/scoped_refptr.h"
16 #include "api/test/mock_video_decoder.h"
17 #include "api/test/mock_video_encoder.h"
18 #include "api/test/videocodec_test_fixture.h"
19 #include "api/video/i420_buffer.h"
20 #include "media/base/media_constants.h"
21 #include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
22 #include "rtc_base/task_queue_for_test.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 #include "test/testsupport/mock/mock_frame_reader.h"
26
27 using ::testing::_;
28 using ::testing::AllOf;
29 using ::testing::Field;
30 using ::testing::Property;
31 using ::testing::ResultOf;
32 using ::testing::Return;
33
34 namespace webrtc {
35 namespace test {
36
37 namespace {
38
39 const int kWidth = 352;
40 const int kHeight = 288;
41 const int kFrameSize = kWidth * kHeight * 3 / 2; // I420.
42
43 } // namespace
44
45 class VideoProcessorTest : public ::testing::Test {
46 protected:
VideoProcessorTest()47 VideoProcessorTest() : q_("VP queue") {
48 config_.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, false, false,
49 false, kWidth, kHeight);
50
51 decoder_mock_ = new MockVideoDecoder();
52 decoders_.push_back(std::unique_ptr<VideoDecoder>(decoder_mock_));
53
54 ExpectInit();
55 EXPECT_CALL(frame_reader_mock_, FrameLength())
56 .WillRepeatedly(Return(kFrameSize));
57 q_.SendTask(
58 [this] {
59 video_processor_ = std::make_unique<VideoProcessor>(
60 &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_,
61 &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr);
62 },
63 RTC_FROM_HERE);
64 }
65
~VideoProcessorTest()66 ~VideoProcessorTest() {
67 q_.SendTask([this] { video_processor_.reset(); }, RTC_FROM_HERE);
68 }
69
ExpectInit()70 void ExpectInit() {
71 EXPECT_CALL(encoder_mock_, InitEncode(_, _)).Times(1);
72 EXPECT_CALL(encoder_mock_, RegisterEncodeCompleteCallback(_)).Times(1);
73 EXPECT_CALL(*decoder_mock_, InitDecode(_, _)).Times(1);
74 EXPECT_CALL(*decoder_mock_, RegisterDecodeCompleteCallback(_)).Times(1);
75 }
76
ExpectRelease()77 void ExpectRelease() {
78 EXPECT_CALL(encoder_mock_, Release()).Times(1);
79 EXPECT_CALL(encoder_mock_, RegisterEncodeCompleteCallback(_)).Times(1);
80 EXPECT_CALL(*decoder_mock_, Release()).Times(1);
81 EXPECT_CALL(*decoder_mock_, RegisterDecodeCompleteCallback(_)).Times(1);
82 }
83
84 TaskQueueForTest q_;
85
86 VideoCodecTestFixture::Config config_;
87
88 MockVideoEncoder encoder_mock_;
89 MockVideoDecoder* decoder_mock_;
90 std::vector<std::unique_ptr<VideoDecoder>> decoders_;
91 MockFrameReader frame_reader_mock_;
92 VideoCodecTestStatsImpl stats_;
93 VideoProcessor::IvfFileWriterMap encoded_frame_writers_;
94 std::unique_ptr<VideoProcessor> video_processor_;
95 };
96
TEST_F(VideoProcessorTest,InitRelease)97 TEST_F(VideoProcessorTest, InitRelease) {
98 ExpectRelease();
99 }
100
TEST_F(VideoProcessorTest,ProcessFrames_FixedFramerate)101 TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
102 const int kBitrateKbps = 456;
103 const int kFramerateFps = 31;
104 EXPECT_CALL(
105 encoder_mock_,
106 SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
107 static_cast<double>(kFramerateFps))))
108 .Times(1);
109 q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
110 RTC_FROM_HERE);
111
112 EXPECT_CALL(frame_reader_mock_, ReadFrame())
113 .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
114 EXPECT_CALL(
115 encoder_mock_,
116 Encode(Property(&VideoFrame::timestamp, 1 * 90000 / kFramerateFps), _))
117 .Times(1);
118 q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
119
120 EXPECT_CALL(
121 encoder_mock_,
122 Encode(Property(&VideoFrame::timestamp, 2 * 90000 / kFramerateFps), _))
123 .Times(1);
124 q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
125
126 ExpectRelease();
127 }
128
TEST_F(VideoProcessorTest,ProcessFrames_VariableFramerate)129 TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
130 const int kBitrateKbps = 456;
131 const int kStartFramerateFps = 27;
132 const int kStartTimestamp = 90000 / kStartFramerateFps;
133 EXPECT_CALL(
134 encoder_mock_,
135 SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
136 static_cast<double>(kStartFramerateFps))))
137 .Times(1);
138 q_.SendTask(
139 [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); },
140 RTC_FROM_HERE);
141
142 EXPECT_CALL(frame_reader_mock_, ReadFrame())
143 .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
144 EXPECT_CALL(encoder_mock_,
145 Encode(Property(&VideoFrame::timestamp, kStartTimestamp), _))
146 .Times(1);
147 q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
148
149 const int kNewFramerateFps = 13;
150 EXPECT_CALL(
151 encoder_mock_,
152 SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
153 static_cast<double>(kNewFramerateFps))))
154 .Times(1);
155 q_.SendTask(
156 [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); },
157 RTC_FROM_HERE);
158
159 EXPECT_CALL(encoder_mock_,
160 Encode(Property(&VideoFrame::timestamp,
161 kStartTimestamp + 90000 / kNewFramerateFps),
162 _))
163 .Times(1);
164 q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
165
166 ExpectRelease();
167 }
168
TEST_F(VideoProcessorTest,SetRates)169 TEST_F(VideoProcessorTest, SetRates) {
170 const uint32_t kBitrateKbps = 123;
171 const int kFramerateFps = 17;
172
173 EXPECT_CALL(
174 encoder_mock_,
175 SetRates(AllOf(ResultOf(
176 [](const VideoEncoder::RateControlParameters& params) {
177 return params.bitrate.get_sum_kbps();
178 },
179 kBitrateKbps),
180 Field(&VideoEncoder::RateControlParameters::framerate_fps,
181 static_cast<double>(kFramerateFps)))))
182 .Times(1);
183 q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
184 RTC_FROM_HERE);
185
186 const uint32_t kNewBitrateKbps = 456;
187 const int kNewFramerateFps = 34;
188 EXPECT_CALL(
189 encoder_mock_,
190 SetRates(AllOf(ResultOf(
191 [](const VideoEncoder::RateControlParameters& params) {
192 return params.bitrate.get_sum_kbps();
193 },
194 kNewBitrateKbps),
195 Field(&VideoEncoder::RateControlParameters::framerate_fps,
196 static_cast<double>(kNewFramerateFps)))))
197 .Times(1);
198 q_.SendTask(
199 [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); },
200 RTC_FROM_HERE);
201
202 ExpectRelease();
203 }
204
205 } // namespace test
206 } // namespace webrtc
207