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

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

Issue 2641463002: Unit test out of band H264 SPS,PPS within RtpStreamReceiver. (Closed)
Patch Set: Add bitstream expectations and rebase on https://codereview.webrtc.org/2638933002/ . Created 3 years, 11 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') | no next file » | 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 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/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/video/rtp_stream_receiver.h"
28
29 using testing::_;
30
31 namespace webrtc {
32
33 namespace {
34
35 const char kNewJitterBufferFieldTrialEnabled[] =
36 "WebRTC-NewVideoJitterBuffer/Enabled/";
37 const uint8_t kH264StartCode[] = {0x00, 0x00, 0x00, 0x01};
38
39 class MockTransport : public Transport {
40 public:
41 MOCK_METHOD3(SendRtp,
42 bool(const uint8_t* packet,
43 size_t length,
44 const PacketOptions& options));
45 MOCK_METHOD2(SendRtcp, bool(const uint8_t* packet, size_t length));
46 };
47
48 class MockNackSender : public NackSender {
49 public:
50 MOCK_METHOD1(SendNack, void(const std::vector<uint16_t>& sequence_numbers));
51 };
52
53 class MockKeyFrameRequestSender : public KeyFrameRequestSender {
54 public:
55 MOCK_METHOD0(RequestKeyFrame, void());
56 };
57
58 class MockOnCompleteFrameCallback
59 : public video_coding::OnCompleteFrameCallback {
60 public:
61 MockOnCompleteFrameCallback() : buffer_(rtc::ByteBuffer::ORDER_NETWORK) {}
62
63 MOCK_METHOD1(DoOnCompleteFrame, void(video_coding::FrameObject* frame));
64 MOCK_METHOD1(DoOnCompleteFrameFailNullptr,
65 void(video_coding::FrameObject* frame));
66 MOCK_METHOD1(DoOnCompleteFrameFailLength,
67 void(video_coding::FrameObject* frame));
68 MOCK_METHOD1(DoOnCompleteFrameFailBitstream,
69 void(video_coding::FrameObject* frame));
70 void OnCompleteFrame(std::unique_ptr<video_coding::FrameObject> frame) {
71 if (!frame) {
72 DoOnCompleteFrameFailNullptr(nullptr);
73 return;
74 }
75 if (buffer_.Length() != frame->size()) {
76 LOG(LS_WARNING) << "length not equal " << buffer_.Length() << " "
77 << frame->size();
sprang_webrtc 2017/01/23 12:57:09 Are you expecting this to happen? I think no one w
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 field_trial::InitFieldTrialsFromString(kNewJitterBufferFieldTrialEnabled);
107 rtp_stream_receiver_.reset(new RtpStreamReceiver(
108 nullptr, nullptr, &mock_transport_, nullptr, nullptr, &packet_router_,
109 nullptr, &config_, nullptr, process_thread_.get(), nullptr,
110 &mock_nack_sender_, &mock_key_frame_request_sender_,
111 &mock_on_complete_frame_callback_, &timing_));
112 }
113
114 WebRtcRTPHeader GetDefaultPacket() {
115 WebRtcRTPHeader packet;
116 memset(&packet, 0, sizeof(packet));
117 packet.type.Video.codec = kRtpVideoH264;
118 return packet;
119 }
120
121 // TODO(Johan): refactor h264_sps_pps_tracker_unittests.cc to avoid duplicate
122 // code.
123 void AddSps(WebRtcRTPHeader* packet, int sps_id, std::vector<uint8_t>* data) {
124 NaluInfo info;
125 info.type = H264::NaluType::kSps;
126 info.sps_id = sps_id;
127 info.pps_id = -1;
128 info.offset = data->size();
129 info.size = 2;
130 data->push_back(H264::NaluType::kSps);
131 data->push_back(sps_id);
132 packet->type.Video.codecHeader.H264
133 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
134 }
135
136 void AddPps(WebRtcRTPHeader* packet,
137 int sps_id,
138 int pps_id,
139 std::vector<uint8_t>* data) {
140 NaluInfo info;
141 info.type = H264::NaluType::kPps;
142 info.sps_id = sps_id;
143 info.pps_id = pps_id;
144 info.offset = data->size();
145 info.size = 2;
146 data->push_back(H264::NaluType::kPps);
147 data->push_back(pps_id);
148 packet->type.Video.codecHeader.H264
149 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
150 }
151
152 void AddIdr(WebRtcRTPHeader* packet, int pps_id) {
153 NaluInfo info;
154 info.type = H264::NaluType::kIdr;
155 info.sps_id = -1;
156 info.pps_id = pps_id;
157 packet->type.Video.codecHeader.H264
158 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
159 }
160
161 protected:
162 static VideoReceiveStream::Config CreateConfig() {
163 VideoReceiveStream::Config config(nullptr);
164 config.rtp.remote_ssrc = 1111;
165 config.rtp.local_ssrc = 2222;
166 return config;
167 }
168
169 VideoReceiveStream::Config config_;
170 MockNackSender mock_nack_sender_;
171 MockKeyFrameRequestSender mock_key_frame_request_sender_;
172 MockTransport mock_transport_;
173 MockOnCompleteFrameCallback mock_on_complete_frame_callback_;
174 PacketRouter packet_router_;
175 VCMTiming timing_;
176 std::unique_ptr<ProcessThread> process_thread_;
177 std::unique_ptr<RtpStreamReceiver> rtp_stream_receiver_;
178 };
179
180 TEST_F(RtpStreamReceiverTest, GenericKeyFrame) {
181 WebRtcRTPHeader rtp_header;
182 const std::vector<uint8_t> data({1, 2, 3, 4});
183 memset(&rtp_header, 0, sizeof(rtp_header));
184 rtp_header.header.sequenceNumber = 1;
185 rtp_header.header.markerBit = 1;
186 rtp_header.type.Video.is_first_packet_in_frame = true;
187 rtp_header.frameType = kVideoFrameKey;
188 rtp_header.type.Video.codec = kRtpVideoGeneric;
189 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
190 data.size());
191 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
192 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
193 &rtp_header);
194 }
195
196 TEST_F(RtpStreamReceiverTest, GenericKeyFrameBitstreamError) {
197 WebRtcRTPHeader rtp_header;
198 const std::vector<uint8_t> data({1, 2, 3, 4});
199 memset(&rtp_header, 0, sizeof(rtp_header));
200 rtp_header.header.sequenceNumber = 1;
201 rtp_header.header.markerBit = 1;
202 rtp_header.type.Video.is_first_packet_in_frame = true;
203 rtp_header.frameType = kVideoFrameKey;
204 rtp_header.type.Video.codec = kRtpVideoGeneric;
205 constexpr uint8_t expected_bitsteam[] = {1, 2, 3, 0xff};
206 mock_on_complete_frame_callback_.AppendExpectedBitstream(
207 expected_bitsteam, sizeof(expected_bitsteam));
208 EXPECT_CALL(mock_on_complete_frame_callback_,
209 DoOnCompleteFrameFailBitstream(_));
210 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
211 &rtp_header);
212 }
213
214 TEST_F(RtpStreamReceiverTest, InBandSpsPps) {
215 std::vector<uint8_t> sps_data;
216 WebRtcRTPHeader sps_packet = GetDefaultPacket();
217 AddSps(&sps_packet, 0, &sps_data);
218 sps_packet.header.sequenceNumber = 0;
219 mock_on_complete_frame_callback_.AppendExpectedBitstream(
220 kH264StartCode, sizeof(kH264StartCode));
221 mock_on_complete_frame_callback_.AppendExpectedBitstream(sps_data.data(),
222 sps_data.size());
223 rtp_stream_receiver_->OnReceivedPayloadData(sps_data.data(), sps_data.size(),
224 &sps_packet);
225
226 std::vector<uint8_t> pps_data;
227 WebRtcRTPHeader pps_packet = GetDefaultPacket();
228 AddPps(&pps_packet, 0, 1, &pps_data);
229 pps_packet.header.sequenceNumber = 1;
230 mock_on_complete_frame_callback_.AppendExpectedBitstream(
231 kH264StartCode, sizeof(kH264StartCode));
232 mock_on_complete_frame_callback_.AppendExpectedBitstream(pps_data.data(),
233 pps_data.size());
234 rtp_stream_receiver_->OnReceivedPayloadData(pps_data.data(), pps_data.size(),
235 &pps_packet);
236
237 std::vector<uint8_t> idr_data;
238 WebRtcRTPHeader idr_packet = GetDefaultPacket();
239 AddIdr(&idr_packet, 1);
240 idr_packet.type.Video.is_first_packet_in_frame = true;
241 idr_packet.header.sequenceNumber = 2;
242 idr_packet.header.markerBit = 1;
243 idr_packet.type.Video.is_first_packet_in_frame = true;
244 idr_packet.frameType = kVideoFrameKey;
245 idr_packet.type.Video.codec = kRtpVideoH264;
246 idr_data.insert(idr_data.end(), {0x65, 1, 2, 3});
247 mock_on_complete_frame_callback_.AppendExpectedBitstream(
248 kH264StartCode, sizeof(kH264StartCode));
249 mock_on_complete_frame_callback_.AppendExpectedBitstream(idr_data.data(),
250 idr_data.size());
251 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
252 rtp_stream_receiver_->OnReceivedPayloadData(idr_data.data(), idr_data.size(),
253 &idr_packet);
254 }
255
256 TEST_F(RtpStreamReceiverTest, OutOfBandFmtpSpsPps) {
257 constexpr int kPayloadType = 99;
258 VideoCodec codec;
259 codec.plType = kPayloadType;
260 std::map<std::string, std::string> codec_params;
261 // Example parameter sets from https://tools.ietf.org/html/rfc3984#section-8.2
262 // .
263 codec_params.insert(
264 {cricket::kH264FmtpSpropParameterSets, "Z0IACpZTBYmI,aMljiA=="});
265 rtp_stream_receiver_->AddReceiveCodec(codec, codec_params);
266 const uint8_t binary_sps[] = {0x67, 0x42, 0x00, 0x0a, 0x96,
267 0x53, 0x05, 0x89, 0x88};
268 mock_on_complete_frame_callback_.AppendExpectedBitstream(
269 kH264StartCode, sizeof(kH264StartCode));
270 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_sps,
271 sizeof(binary_sps));
272 const uint8_t binary_pps[] = {0x68, 0xc9, 0x63, 0x88};
273 mock_on_complete_frame_callback_.AppendExpectedBitstream(
274 kH264StartCode, sizeof(kH264StartCode));
275 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_pps,
276 sizeof(binary_pps));
277
278 std::vector<uint8_t> data;
279 WebRtcRTPHeader idr_packet = GetDefaultPacket();
280 AddIdr(&idr_packet, 0);
281 idr_packet.header.payloadType = kPayloadType;
282 idr_packet.type.Video.is_first_packet_in_frame = true;
283 idr_packet.header.sequenceNumber = 2;
284 idr_packet.header.markerBit = 1;
285 idr_packet.type.Video.is_first_packet_in_frame = true;
286 idr_packet.frameType = kVideoFrameKey;
287 idr_packet.type.Video.codec = kRtpVideoH264;
288 data.insert(data.end(), {1, 2, 3});
289 mock_on_complete_frame_callback_.AppendExpectedBitstream(
290 kH264StartCode, sizeof(kH264StartCode));
291 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
292 data.size());
293 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
294 rtp_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
295 &idr_packet);
296 }
297
298 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/rtp_stream_receiver.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698