OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 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 "webrtc/test/gtest.h" | |
12 #include "webrtc/test/gmock.h" | |
13 | |
14 #include "webrtc/base/logging.h" | |
15 #include "webrtc/common_video/h264/h264_common.h" | |
16 #include "webrtc/media/base/mediaconstants.h" | |
17 #include "webrtc/modules/pacing/packet_router.h" | |
18 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | |
19 #include "webrtc/modules/video_coding/frame_object.h" | |
20 #include "webrtc/modules/video_coding/packet.h" | |
21 #include "webrtc/modules/video_coding/rtp_frame_reference_finder.h" | |
22 #include "webrtc/modules/video_coding/timing.h" | |
23 #include "webrtc/modules/utility/include/process_thread.h" | |
24 #include "webrtc/system_wrappers/include/clock.h" | |
25 #include "webrtc/system_wrappers/include/field_trial_default.h" | |
26 #include "webrtc/video/rtp_stream_receiver.h" | |
27 | |
28 namespace webrtc { | |
29 | |
30 namespace { | |
31 | |
32 const char new_jb_enabled[] = "WebRTC-NewVideoJitterBuffer/Enabled/"; | |
sprang_webrtc
2017/01/18 10:05:11
I'd change the name to something like kNewJitterBu
| |
33 | |
34 class MockTransport : public Transport { | |
35 public: | |
36 MOCK_METHOD3(SendRtp, | |
37 bool(const uint8_t* packet, | |
38 size_t length, | |
39 const PacketOptions& options)); | |
40 MOCK_METHOD2(SendRtcp, bool(const uint8_t* packet, size_t length)); | |
41 }; | |
42 | |
43 class MockNackSender : public NackSender { | |
44 public: | |
45 MOCK_METHOD1(SendNack, void(const std::vector<uint16_t>& sequence_numbers)); | |
46 }; | |
47 | |
48 class MockKeyFrameRequestSender : public KeyFrameRequestSender { | |
49 public: | |
50 MOCK_METHOD0(RequestKeyFrame, void()); | |
51 }; | |
52 | |
53 class MockOnCompleteFrameCallback | |
54 : public video_coding::OnCompleteFrameCallback { | |
55 public: | |
56 MOCK_METHOD1(DoOnCompleteFrame, void(video_coding::FrameObject* frame)); | |
57 void OnCompleteFrame(std::unique_ptr<video_coding::FrameObject> frame) { | |
58 DoOnCompleteFrame(frame.get()); | |
59 } | |
60 }; | |
61 | |
62 } // namespace | |
63 | |
64 class RtpStreamReceiverTest : public testing::Test { | |
65 public: | |
66 RtpStreamReceiverTest() | |
67 : config_(CreateConfig()), | |
68 timing_(Clock::GetRealTimeClock()), | |
69 process_thread_(ProcessThread::Create("TestThread")) { | |
70 // InitFieldTrials has to done before creation of rtp_stream_receiver_. | |
sprang_webrtc
2017/01/18 10:05:10
nit: s/has to done/has to be done
Or you can move
johan
2017/01/18 12:38:29
Ack
sprang_webrtc
2017/01/23 12:57:09
I don't have super strong preferences, but if the
| |
71 field_trial::InitFieldTrialsFromString(new_jb_enabled); | |
72 rtp_stream_receiver_.reset(new RtpStreamReceiver( | |
73 nullptr, nullptr, &mock_transport_, nullptr, nullptr, &packet_router_, | |
74 nullptr, &config_, nullptr, process_thread_.get(), nullptr, | |
75 &mock_nack_sender_, &mock_key_frame_request_sender_, | |
76 &mock_on_complete_frame_callback_, &timing_)); | |
77 } | |
78 | |
79 WebRtcRTPHeader GetDefaultPacket() { | |
80 WebRtcRTPHeader packet; | |
81 memset(&packet, 0, sizeof(packet)); | |
82 packet.type.Video.codec = kRtpVideoH264; | |
83 return packet; | |
84 } | |
85 | |
86 // TODO(Johan): refactor h264_sps_pps_tracker_unittests.cc to avoid duplicate | |
87 // code. | |
88 void AddSps(WebRtcRTPHeader* packet, int sps_id, std::vector<uint8_t>* data) { | |
89 NaluInfo info; | |
90 info.type = H264::NaluType::kSps; | |
91 info.sps_id = sps_id; | |
92 info.pps_id = -1; | |
93 info.offset = data->size(); | |
94 info.size = 2; | |
95 data->push_back(H264::NaluType::kSps); | |
96 data->push_back(sps_id); | |
97 packet->type.Video.codecHeader.H264 | |
98 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info; | |
99 } | |
100 | |
101 void AddPps(WebRtcRTPHeader* packet, | |
102 int sps_id, | |
103 int pps_id, | |
104 std::vector<uint8_t>* data) { | |
105 NaluInfo info; | |
106 info.type = H264::NaluType::kPps; | |
107 info.sps_id = sps_id; | |
108 info.pps_id = pps_id; | |
109 info.offset = data->size(); | |
110 info.size = 2; | |
111 data->push_back(H264::NaluType::kPps); | |
112 data->push_back(pps_id); | |
113 packet->type.Video.codecHeader.H264 | |
114 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info; | |
115 } | |
116 | |
117 void AddIdr(WebRtcRTPHeader* packet, int pps_id) { | |
118 NaluInfo info; | |
119 info.type = H264::NaluType::kIdr; | |
120 info.sps_id = -1; | |
121 info.pps_id = pps_id; | |
122 packet->type.Video.codecHeader.H264 | |
123 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info; | |
124 } | |
125 | |
126 protected: | |
127 static VideoReceiveStream::Config CreateConfig() { | |
128 VideoReceiveStream::Config config(nullptr); | |
129 config.rtp.remote_ssrc = 1111; | |
130 config.rtp.local_ssrc = 2222; | |
131 return config; | |
132 } | |
sprang_webrtc
2017/01/18 10:05:10
nit: \n
| |
133 VideoReceiveStream::Config config_; | |
134 MockNackSender mock_nack_sender_; | |
135 MockKeyFrameRequestSender mock_key_frame_request_sender_; | |
136 MockTransport mock_transport_; | |
137 MockOnCompleteFrameCallback mock_on_complete_frame_callback_; | |
138 PacketRouter packet_router_; | |
139 VCMTiming timing_; | |
140 std::unique_ptr<ProcessThread> process_thread_; | |
141 std::unique_ptr<RtpStreamReceiver> rtp_stream_receiver_; | |
142 }; | |
143 | |
144 TEST_F(RtpStreamReceiverTest, GenericKeyFrame) { | |
145 WebRtcRTPHeader rtp_header; | |
146 const std::vector<uint8_t> data({1, 2, 3, 4}); | |
147 memset(&rtp_header, 0, sizeof(rtp_header)); | |
148 rtp_header.header.sequenceNumber = 1; | |
149 rtp_header.header.markerBit = 1; | |
150 rtp_header.type.Video.is_first_packet_in_frame = true; | |
151 rtp_header.frameType = kVideoFrameKey; | |
152 rtp_header.type.Video.codec = kRtpVideoGeneric; | |
153 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(testing::_)); | |
sprang_webrtc
2017/01/18 10:05:10
add "using ::testing::_;" above
johan
2017/01/18 12:38:30
Acknowledged.
| |
154 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(), | |
155 &rtp_header); | |
156 } | |
157 | |
158 TEST_F(RtpStreamReceiverTest, InBandSpsPps) { | |
159 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(testing::_)); | |
sprang_webrtc
2017/01/18 10:05:10
When do we expect it? If it's a result of rtp_stre
johan
2017/01/18 12:38:30
OK
| |
160 std::vector<uint8_t> data; | |
161 WebRtcRTPHeader sps_pps_packet = GetDefaultPacket(); | |
162 | |
163 AddSps(&sps_pps_packet, 0, &data); | |
164 sps_pps_packet.header.sequenceNumber = 0; | |
165 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(), | |
166 &sps_pps_packet); | |
167 data.clear(); | |
168 AddPps(&sps_pps_packet, 0, 1, &data); | |
169 sps_pps_packet.header.sequenceNumber = 1; | |
170 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(), | |
171 &sps_pps_packet); | |
172 data.clear(); | |
173 | |
174 WebRtcRTPHeader idr_packet = GetDefaultPacket(); | |
175 AddIdr(&idr_packet, 1); | |
176 idr_packet.type.Video.is_first_packet_in_frame = true; | |
177 idr_packet.header.sequenceNumber = 2; | |
178 idr_packet.header.markerBit = 1; | |
179 idr_packet.type.Video.is_first_packet_in_frame = true; | |
180 idr_packet.frameType = kVideoFrameKey; | |
181 idr_packet.type.Video.codec = kRtpVideoH264; | |
182 data.insert(data.end(), {1, 2, 3}); | |
183 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(), | |
184 &idr_packet); | |
185 } | |
186 | |
187 TEST_F(RtpStreamReceiverTest, OutOfBandFmtpSpsPps) { | |
188 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(testing::_)); | |
sprang_webrtc
2017/01/18 10:05:10
Same here
| |
189 constexpr int payload_type = 99; | |
sprang_webrtc
2017/01/18 10:05:11
kPayloadType
| |
190 VideoCodec codec; | |
191 codec.plType = payload_type; | |
192 std::map<std::string, std::string> codec_params; | |
193 // Example parameter sets from https://tools.ietf.org/html/rfc3984#section-8.2 | |
194 // . | |
195 codec_params.insert( | |
196 {cricket::kH264FmtpSpropParameterSets, "Z0IACpZTBYmI,aMljiA=="}); | |
197 rtp_stream_receiver_->AddReceiveCodec(codec, codec_params); | |
198 | |
199 std::vector<uint8_t> data; | |
200 WebRtcRTPHeader idr_packet = GetDefaultPacket(); | |
201 AddIdr(&idr_packet, 0); | |
202 idr_packet.header.payloadType = payload_type; | |
203 idr_packet.type.Video.is_first_packet_in_frame = true; | |
204 idr_packet.header.sequenceNumber = 2; | |
205 idr_packet.header.markerBit = 1; | |
206 idr_packet.type.Video.is_first_packet_in_frame = true; | |
207 idr_packet.frameType = kVideoFrameKey; | |
208 idr_packet.type.Video.codec = kRtpVideoH264; | |
209 data.insert(data.end(), {1, 2, 3}); | |
210 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(), | |
211 &idr_packet); | |
212 } | |
213 | |
214 } // namespace webrtc | |
OLD | NEW |