• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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