Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: webrtc/video/vie_encoder_unittest.cc

Issue 2060403002: Add task queue to Call. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@move_getpadding
Patch Set: Fix audio thread check when adding audio to bitrateallocator. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 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 "testing/gtest/include/gtest/gtest.h"
12 #include "webrtc/base/logging.h"
13 #include "webrtc/test/encoder_settings.h"
14 #include "webrtc/test/fake_encoder.h"
15 #include "webrtc/video/send_statistics_proxy.h"
16 #include "webrtc/video/vie_encoder.h"
17
18 namespace webrtc {
19
20 class ViEEncoderTest : public ::testing::Test {
21 public:
22 static const int kDefaultTimeoutMs = 30 * 1000;
23
24 ViEEncoderTest()
25 : video_send_config_(VideoSendStream::Config(nullptr)),
26 fake_encoder_(),
27 stats_proxy_(Clock::GetRealTimeClock(),
28 video_send_config_,
29 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo),
30 sink_(&fake_encoder_) {}
31
32 void SetUp() override {
33 video_send_config_ = VideoSendStream::Config(nullptr);
34 video_send_config_.encoder_settings.encoder = &fake_encoder_;
35 video_send_config_.encoder_settings.payload_name = "FAKE";
36 video_send_config_.encoder_settings.payload_type = 125;
37
38 video_encoder_config_.streams = test::CreateVideoStreams(1);
39
40 vie_encoder_.reset(new ViEEncoder(
41 1 /* number_of_cores */, &stats_proxy_,
42 video_send_config_.encoder_settings, nullptr /* pre_encode_callback */,
43 nullptr /* overuse_callback */, nullptr /* encoder_timing */));
44 vie_encoder_->SetSink(&sink_);
45 vie_encoder_->SetStartBitrate(10000);
46 vie_encoder_->ConfigureEncoder(video_encoder_config_, 1440);
47 }
48
49 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
50 class TestBuffer : public webrtc::I420Buffer {
51 public:
52 TestBuffer(rtc::Event* event, int width, int height)
53 : I420Buffer(width, height), event_(event) {}
54
55 private:
56 friend class rtc::RefCountedObject<TestBuffer>;
57 ~TestBuffer() override {
58 if (event_)
59 event_->Set();
60 }
61 rtc::Event* const event_;
62 };
63
64 VideoFrame frame(
65 new rtc::RefCountedObject<TestBuffer>(
66 destruction_event,
67 static_cast<int>(video_encoder_config_.streams[0].width),
68 static_cast<int>(video_encoder_config_.streams[0].height)),
69 99, 99, kVideoRotation_0);
70 frame.set_ntp_time_ms(ntp_ts);
71 return frame;
72 }
73
74 class TestEncoder : public test::FakeEncoder {
75 public:
76 TestEncoder()
77 : FakeEncoder(Clock::GetRealTimeClock()),
78 continue_encode_event_(false, false) {}
79
80 int32_t Encode(const VideoFrame& input_image,
81 const CodecSpecificInfo* codec_specific_info,
82 const std::vector<FrameType>* frame_types) override {
83 bool block_encode;
84 {
85 rtc::CritScope lock(&crit_);
86 EXPECT_GT(input_image.timestamp(), timestamp_);
87 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
88 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
89
90 timestamp_ = input_image.timestamp();
91 ntp_time_ms_ = input_image.ntp_time_ms();
92 block_encode = block_next_encode_;
93 block_next_encode_ = false;
94 }
95 int32_t result =
96 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
97 if (block_encode)
98 continue_encode_event_.Wait(kDefaultTimeoutMs);
99 return result;
100 }
101
102 void BlockNextEncode() {
103 rtc::CritScope lock(&crit_);
104 block_next_encode_ = true;
105 }
106
107 void ContinueEncode() { continue_encode_event_.Set(); }
108
109 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
110 uint32_t timestamp) const {
111 rtc::CritScope lock(&crit_);
112 EXPECT_EQ(timestamp_, timestamp);
113 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
114 }
115
116 private:
117 rtc::CriticalSection crit_;
118 bool block_next_encode_ = false;
119 rtc::Event continue_encode_event_;
120 uint32_t timestamp_ = 0;
121 int64_t ntp_time_ms_ = 0;
122 };
123
124 class TestSink : public EncodedImageCallback {
125 public:
126 explicit TestSink(TestEncoder* test_encoder)
127 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
128
129 int32_t Encoded(const EncodedImage& encoded_image,
130 const CodecSpecificInfo* codec_specific_info,
131 const RTPFragmentationHeader* fragmentation) override {
132 rtc::CritScope lock(&crit_);
133 EXPECT_TRUE(expect_frames_);
134 timestamp_ = encoded_image._timeStamp;
135 encoded_frame_event_.Set();
136 return 0;
137 }
138
139 void WaitForEncodedFrame(int64_t expected_ntp_time) {
140 uint32_t timestamp = 0;
141 encoded_frame_event_.Wait(kDefaultTimeoutMs);
142 {
143 rtc::CritScope lock(&crit_);
144 timestamp = timestamp_;
145 }
146 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
147 }
148
149 void SetExpectNoFrames() {
150 rtc::CritScope lock(&crit_);
151 expect_frames_ = false;
152 }
153
154 private:
155 rtc::CriticalSection crit_;
156 TestEncoder* test_encoder_;
157 rtc::Event encoded_frame_event_;
158 uint32_t timestamp_ = 0;
159 bool expect_frames_ = true;
160 };
161
162 VideoSendStream::Config video_send_config_;
163 VideoEncoderConfig video_encoder_config_;
164 TestEncoder fake_encoder_;
165 SendStatisticsProxy stats_proxy_;
166 TestSink sink_;
167 std::unique_ptr<ViEEncoder> vie_encoder_;
168 };
169
170 TEST_F(ViEEncoderTest, EncodeOneFrame) {
171 const int kTargetBitrateBps = 100000;
172 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
173 rtc::Event frame_destroyed_event(false, false);
174 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
175 sink_.WaitForEncodedFrame(1);
176 frame_destroyed_event.Wait(kDefaultTimeoutMs);
177 vie_encoder_->Stop();
178 }
179
180 TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
181 // Dropped since no target bitrate has been set.
182 rtc::Event frame_destroyed_event(false, false);
183 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
184 frame_destroyed_event.Wait(kDefaultTimeoutMs);
185
186 const int kTargetBitrateBps = 100000;
187 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
188
189 vie_encoder_->IncomingCapturedFrame(CreateFrame(2, nullptr));
190 sink_.WaitForEncodedFrame(2);
191 vie_encoder_->Stop();
192 }
193
194 TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
195 const int kTargetBitrateBps = 100000;
196 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
197 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, nullptr));
198 sink_.WaitForEncodedFrame(1);
199
200 vie_encoder_->OnBitrateUpdated(0, 0, 0);
201 // Dropped since bitrate is zero.
202 vie_encoder_->IncomingCapturedFrame(CreateFrame(2, nullptr));
203
204 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
205 vie_encoder_->IncomingCapturedFrame(CreateFrame(3, nullptr));
206 sink_.WaitForEncodedFrame(3);
207 vie_encoder_->Stop();
208 }
209
210 TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
211 const int kTargetBitrateBps = 100000;
212 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
213 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, nullptr));
214 sink_.WaitForEncodedFrame(1);
215
216 // This frame will be dropped since it has the same ntp timestamp.
217 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, nullptr));
218
219 vie_encoder_->IncomingCapturedFrame(CreateFrame(2, nullptr));
220 sink_.WaitForEncodedFrame(2);
221 vie_encoder_->Stop();
222 }
223
224 TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
225 const int kTargetBitrateBps = 100000;
226 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
227
228 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, nullptr));
229 sink_.WaitForEncodedFrame(1);
230
231 vie_encoder_->Stop();
232 sink_.SetExpectNoFrames();
233 rtc::Event frame_destroyed_event(false, false);
234 vie_encoder_->IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
235 frame_destroyed_event.Wait(kDefaultTimeoutMs);
236 }
237
238 TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
239 const int kTargetBitrateBps = 100000;
240 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
241
242 fake_encoder_.BlockNextEncode();
243 vie_encoder_->IncomingCapturedFrame(CreateFrame(1, nullptr));
244 sink_.WaitForEncodedFrame(1);
245 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
246 // call to ContinueEncode.
247 vie_encoder_->IncomingCapturedFrame(CreateFrame(2, nullptr));
248 vie_encoder_->IncomingCapturedFrame(CreateFrame(3, nullptr));
249 fake_encoder_.ContinueEncode();
250 sink_.WaitForEncodedFrame(3);
251
252 vie_encoder_->Stop();
253 }
254
255 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698