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

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

Issue 2926253002: Rename class RtpStreamReceiver --> RtpVideoStreamReceiver. (Closed)
Patch Set: Created 3 years, 6 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
« no previous file with comments | « webrtc/video/rtp_stream_receiver.cc ('k') | webrtc/video/rtp_video_stream_receiver.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2017 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 "webrtc/test/gtest.h"
12 #include "webrtc/test/gmock.h"
13
14 #include "webrtc/base/bytebuffer.h"
15 #include "webrtc/base/logging.h"
16 #include "webrtc/common_video/h264/h264_common.h"
17 #include "webrtc/media/base/mediaconstants.h"
18 #include "webrtc/modules/pacing/packet_router.h"
19 #include "webrtc/modules/video_coding/include/video_coding_defines.h"
20 #include "webrtc/modules/video_coding/frame_object.h"
21 #include "webrtc/modules/video_coding/packet.h"
22 #include "webrtc/modules/video_coding/rtp_frame_reference_finder.h"
23 #include "webrtc/modules/video_coding/timing.h"
24 #include "webrtc/modules/utility/include/process_thread.h"
25 #include "webrtc/system_wrappers/include/clock.h"
26 #include "webrtc/system_wrappers/include/field_trial_default.h"
27 #include "webrtc/test/field_trial.h"
28 #include "webrtc/video/rtp_stream_receiver.h"
29
30 using testing::_;
31
32 namespace webrtc {
33
34 namespace {
35
36 const char kNewJitterBufferFieldTrialEnabled[] =
37 "WebRTC-NewVideoJitterBuffer/Enabled/";
38 const uint8_t kH264StartCode[] = {0x00, 0x00, 0x00, 0x01};
39
40 class MockTransport : public Transport {
41 public:
42 MOCK_METHOD3(SendRtp,
43 bool(const uint8_t* packet,
44 size_t length,
45 const PacketOptions& options));
46 MOCK_METHOD2(SendRtcp, bool(const uint8_t* packet, size_t length));
47 };
48
49 class MockNackSender : public NackSender {
50 public:
51 MOCK_METHOD1(SendNack, void(const std::vector<uint16_t>& sequence_numbers));
52 };
53
54 class MockKeyFrameRequestSender : public KeyFrameRequestSender {
55 public:
56 MOCK_METHOD0(RequestKeyFrame, void());
57 };
58
59 class MockOnCompleteFrameCallback
60 : public video_coding::OnCompleteFrameCallback {
61 public:
62 MockOnCompleteFrameCallback() : buffer_(rtc::ByteBuffer::ORDER_NETWORK) {}
63
64 MOCK_METHOD1(DoOnCompleteFrame, void(video_coding::FrameObject* frame));
65 MOCK_METHOD1(DoOnCompleteFrameFailNullptr,
66 void(video_coding::FrameObject* frame));
67 MOCK_METHOD1(DoOnCompleteFrameFailLength,
68 void(video_coding::FrameObject* frame));
69 MOCK_METHOD1(DoOnCompleteFrameFailBitstream,
70 void(video_coding::FrameObject* frame));
71 void OnCompleteFrame(std::unique_ptr<video_coding::FrameObject> frame) {
72 if (!frame) {
73 DoOnCompleteFrameFailNullptr(nullptr);
74 return;
75 }
76 EXPECT_EQ(buffer_.Length(), frame->size());
77 if (buffer_.Length() != frame->size()) {
78 DoOnCompleteFrameFailLength(frame.get());
79 return;
80 }
81 std::vector<uint8_t> actual_data(frame->size());
82 frame->GetBitstream(actual_data.data());
83 if (memcmp(buffer_.Data(), actual_data.data(), buffer_.Length()) != 0) {
84 DoOnCompleteFrameFailBitstream(frame.get());
85 return;
86 }
87 DoOnCompleteFrame(frame.get());
88 }
89 void AppendExpectedBitstream(const uint8_t data[], size_t size_in_bytes) {
90 // TODO(Johan): Let rtc::ByteBuffer handle uint8_t* instead of char*.
91 buffer_.WriteBytes(reinterpret_cast<const char*>(data), size_in_bytes);
92 }
93 rtc::ByteBufferWriter buffer_;
94 };
95
96 } // namespace
97
98 class RtpStreamReceiverTest : public testing::Test {
99 public:
100 RtpStreamReceiverTest()
101 : config_(CreateConfig()),
102 timing_(Clock::GetRealTimeClock()),
103 process_thread_(ProcessThread::Create("TestThread")) {}
104
105 void SetUp() {
106 rtp_stream_receiver_.reset(new RtpStreamReceiver(
107 &mock_transport_, nullptr, &packet_router_, &config_,
108 nullptr, process_thread_.get(), &mock_nack_sender_,
109 &mock_key_frame_request_sender_, &mock_on_complete_frame_callback_,
110 &timing_));
111 }
112
113 WebRtcRTPHeader GetDefaultPacket() {
114 WebRtcRTPHeader packet;
115 memset(&packet, 0, sizeof(packet));
116 packet.type.Video.codec = kRtpVideoH264;
117 return packet;
118 }
119
120 // TODO(Johan): refactor h264_sps_pps_tracker_unittests.cc to avoid duplicate
121 // code.
122 void AddSps(WebRtcRTPHeader* packet, int sps_id, std::vector<uint8_t>* data) {
123 NaluInfo info;
124 info.type = H264::NaluType::kSps;
125 info.sps_id = sps_id;
126 info.pps_id = -1;
127 info.offset = data->size();
128 info.size = 2;
129 data->push_back(H264::NaluType::kSps);
130 data->push_back(sps_id);
131 packet->type.Video.codecHeader.H264
132 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
133 }
134
135 void AddPps(WebRtcRTPHeader* packet,
136 int sps_id,
137 int pps_id,
138 std::vector<uint8_t>* data) {
139 NaluInfo info;
140 info.type = H264::NaluType::kPps;
141 info.sps_id = sps_id;
142 info.pps_id = pps_id;
143 info.offset = data->size();
144 info.size = 2;
145 data->push_back(H264::NaluType::kPps);
146 data->push_back(pps_id);
147 packet->type.Video.codecHeader.H264
148 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
149 }
150
151 void AddIdr(WebRtcRTPHeader* packet, int pps_id) {
152 NaluInfo info;
153 info.type = H264::NaluType::kIdr;
154 info.sps_id = -1;
155 info.pps_id = pps_id;
156 packet->type.Video.codecHeader.H264
157 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
158 }
159
160 protected:
161 static VideoReceiveStream::Config CreateConfig() {
162 VideoReceiveStream::Config config(nullptr);
163 config.rtp.remote_ssrc = 1111;
164 config.rtp.local_ssrc = 2222;
165 return config;
166 }
167
168 webrtc::test::ScopedFieldTrials override_field_trials_{
169 kNewJitterBufferFieldTrialEnabled};
170 VideoReceiveStream::Config config_;
171 MockNackSender mock_nack_sender_;
172 MockKeyFrameRequestSender mock_key_frame_request_sender_;
173 MockTransport mock_transport_;
174 MockOnCompleteFrameCallback mock_on_complete_frame_callback_;
175 PacketRouter packet_router_;
176 VCMTiming timing_;
177 std::unique_ptr<ProcessThread> process_thread_;
178 std::unique_ptr<RtpStreamReceiver> rtp_stream_receiver_;
179 };
180
181 TEST_F(RtpStreamReceiverTest, GenericKeyFrame) {
182 WebRtcRTPHeader rtp_header;
183 const std::vector<uint8_t> data({1, 2, 3, 4});
184 memset(&rtp_header, 0, sizeof(rtp_header));
185 rtp_header.header.sequenceNumber = 1;
186 rtp_header.header.markerBit = 1;
187 rtp_header.type.Video.is_first_packet_in_frame = true;
188 rtp_header.frameType = kVideoFrameKey;
189 rtp_header.type.Video.codec = kRtpVideoGeneric;
190 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
191 data.size());
192 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
193 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
194 &rtp_header);
195 }
196
197 TEST_F(RtpStreamReceiverTest, GenericKeyFrameBitstreamError) {
198 WebRtcRTPHeader rtp_header;
199 const std::vector<uint8_t> data({1, 2, 3, 4});
200 memset(&rtp_header, 0, sizeof(rtp_header));
201 rtp_header.header.sequenceNumber = 1;
202 rtp_header.header.markerBit = 1;
203 rtp_header.type.Video.is_first_packet_in_frame = true;
204 rtp_header.frameType = kVideoFrameKey;
205 rtp_header.type.Video.codec = kRtpVideoGeneric;
206 constexpr uint8_t expected_bitsteam[] = {1, 2, 3, 0xff};
207 mock_on_complete_frame_callback_.AppendExpectedBitstream(
208 expected_bitsteam, sizeof(expected_bitsteam));
209 EXPECT_CALL(mock_on_complete_frame_callback_,
210 DoOnCompleteFrameFailBitstream(_));
211 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
212 &rtp_header);
213 }
214
215 TEST_F(RtpStreamReceiverTest, InBandSpsPps) {
216 std::vector<uint8_t> sps_data;
217 WebRtcRTPHeader sps_packet = GetDefaultPacket();
218 AddSps(&sps_packet, 0, &sps_data);
219 sps_packet.header.sequenceNumber = 0;
220 mock_on_complete_frame_callback_.AppendExpectedBitstream(
221 kH264StartCode, sizeof(kH264StartCode));
222 mock_on_complete_frame_callback_.AppendExpectedBitstream(sps_data.data(),
223 sps_data.size());
224 rtp_stream_receiver_->OnReceivedPayloadData(sps_data.data(), sps_data.size(),
225 &sps_packet);
226
227 std::vector<uint8_t> pps_data;
228 WebRtcRTPHeader pps_packet = GetDefaultPacket();
229 AddPps(&pps_packet, 0, 1, &pps_data);
230 pps_packet.header.sequenceNumber = 1;
231 mock_on_complete_frame_callback_.AppendExpectedBitstream(
232 kH264StartCode, sizeof(kH264StartCode));
233 mock_on_complete_frame_callback_.AppendExpectedBitstream(pps_data.data(),
234 pps_data.size());
235 rtp_stream_receiver_->OnReceivedPayloadData(pps_data.data(), pps_data.size(),
236 &pps_packet);
237
238 std::vector<uint8_t> idr_data;
239 WebRtcRTPHeader idr_packet = GetDefaultPacket();
240 AddIdr(&idr_packet, 1);
241 idr_packet.type.Video.is_first_packet_in_frame = true;
242 idr_packet.header.sequenceNumber = 2;
243 idr_packet.header.markerBit = 1;
244 idr_packet.type.Video.is_first_packet_in_frame = true;
245 idr_packet.frameType = kVideoFrameKey;
246 idr_packet.type.Video.codec = kRtpVideoH264;
247 idr_data.insert(idr_data.end(), {0x65, 1, 2, 3});
248 mock_on_complete_frame_callback_.AppendExpectedBitstream(
249 kH264StartCode, sizeof(kH264StartCode));
250 mock_on_complete_frame_callback_.AppendExpectedBitstream(idr_data.data(),
251 idr_data.size());
252 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
253 rtp_stream_receiver_->OnReceivedPayloadData(idr_data.data(), idr_data.size(),
254 &idr_packet);
255 }
256
257 TEST_F(RtpStreamReceiverTest, OutOfBandFmtpSpsPps) {
258 constexpr int kPayloadType = 99;
259 VideoCodec codec;
260 codec.plType = kPayloadType;
261 std::map<std::string, std::string> codec_params;
262 // Example parameter sets from https://tools.ietf.org/html/rfc3984#section-8.2
263 // .
264 codec_params.insert(
265 {cricket::kH264FmtpSpropParameterSets, "Z0IACpZTBYmI,aMljiA=="});
266 rtp_stream_receiver_->AddReceiveCodec(codec, codec_params);
267 const uint8_t binary_sps[] = {0x67, 0x42, 0x00, 0x0a, 0x96,
268 0x53, 0x05, 0x89, 0x88};
269 mock_on_complete_frame_callback_.AppendExpectedBitstream(
270 kH264StartCode, sizeof(kH264StartCode));
271 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_sps,
272 sizeof(binary_sps));
273 const uint8_t binary_pps[] = {0x68, 0xc9, 0x63, 0x88};
274 mock_on_complete_frame_callback_.AppendExpectedBitstream(
275 kH264StartCode, sizeof(kH264StartCode));
276 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_pps,
277 sizeof(binary_pps));
278
279 std::vector<uint8_t> data;
280 WebRtcRTPHeader idr_packet = GetDefaultPacket();
281 AddIdr(&idr_packet, 0);
282 idr_packet.header.payloadType = kPayloadType;
283 idr_packet.type.Video.is_first_packet_in_frame = true;
284 idr_packet.header.sequenceNumber = 2;
285 idr_packet.header.markerBit = 1;
286 idr_packet.type.Video.is_first_packet_in_frame = true;
287 idr_packet.frameType = kVideoFrameKey;
288 idr_packet.type.Video.codec = kRtpVideoH264;
289 data.insert(data.end(), {1, 2, 3});
290 mock_on_complete_frame_callback_.AppendExpectedBitstream(
291 kH264StartCode, sizeof(kH264StartCode));
292 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
293 data.size());
294 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
295 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
296 &idr_packet);
297 }
298
299 TEST_F(RtpStreamReceiverTest, PaddingInMediaStream) {
300 WebRtcRTPHeader header = GetDefaultPacket();
301 std::vector<uint8_t> data;
302 data.insert(data.end(), {1, 2, 3});
303 header.header.payloadType = 99;
304 header.type.Video.is_first_packet_in_frame = true;
305 header.header.sequenceNumber = 2;
306 header.header.markerBit = true;
307 header.frameType = kVideoFrameKey;
308 header.type.Video.codec = kRtpVideoGeneric;
309 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
310 data.size());
311
312 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
313 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
314 &header);
315
316 header.header.sequenceNumber = 3;
317 rtp_stream_receiver_->OnReceivedPayloadData(nullptr, 0, &header);
318
319 header.frameType = kVideoFrameDelta;
320 header.header.sequenceNumber = 4;
321 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
322 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
323 &header);
324
325 header.header.sequenceNumber = 6;
326 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
327 &header);
328
329 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
330 header.header.sequenceNumber = 5;
331 rtp_stream_receiver_->OnReceivedPayloadData(nullptr, 0, &header);
332 }
333
334 TEST_F(RtpStreamReceiverTest, RequestKeyframeIfFirstFrameIsDelta) {
335 WebRtcRTPHeader rtp_header;
336 const std::vector<uint8_t> data({1, 2, 3, 4});
337 memset(&rtp_header, 0, sizeof(rtp_header));
338 rtp_header.header.sequenceNumber = 1;
339 rtp_header.header.markerBit = 1;
340 rtp_header.type.Video.is_first_packet_in_frame = true;
341 rtp_header.frameType = kVideoFrameDelta;
342 rtp_header.type.Video.codec = kRtpVideoGeneric;
343
344 EXPECT_CALL(mock_key_frame_request_sender_, RequestKeyFrame());
345 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
346 &rtp_header);
347 }
348
349 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/rtp_stream_receiver.cc ('k') | webrtc/video/rtp_video_stream_receiver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698