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

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

Issue 1250383003: Revert "Renamed the ACMDump to RtcEventLog and moved it to webrtc/video, since it is not specific t… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 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
« no previous file with comments | « webrtc/video/rtc_event_log.proto ('k') | webrtc/webrtc.gyp » ('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 (c) 2015 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 #ifdef ENABLE_RTC_EVENT_LOG
12
13 #include <stdio.h>
14 #include <string>
15 #include <vector>
16
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/base/checks.h"
19 #include "webrtc/base/scoped_ptr.h"
20 #include "webrtc/call.h"
21 #include "webrtc/system_wrappers/interface/clock.h"
22 #include "webrtc/test/test_suite.h"
23 #include "webrtc/test/testsupport/fileutils.h"
24 #include "webrtc/test/testsupport/gtest_disable.h"
25 #include "webrtc/video/rtc_event_log.h"
26
27 // Files generated at build-time by the protobuf compiler.
28 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
29 #include "external/webrtc/webrtc/video/rtc_event_log.pb.h"
30 #else
31 #include "webrtc/video/rtc_event_log.pb.h"
32 #endif
33
34 namespace webrtc {
35
36 // TODO(terelius): Place this definition with other parsing functions?
37 MediaType GetRuntimeMediaType(rtclog::MediaType media_type) {
38 switch (media_type) {
39 case rtclog::MediaType::ANY:
40 return MediaType::ANY;
41 case rtclog::MediaType::AUDIO:
42 return MediaType::AUDIO;
43 case rtclog::MediaType::VIDEO:
44 return MediaType::VIDEO;
45 case rtclog::MediaType::DATA:
46 return MediaType::DATA;
47 }
48 RTC_NOTREACHED();
49 return MediaType::ANY;
50 }
51
52 // Checks that the event has a timestamp, a type and exactly the data field
53 // corresponding to the type.
54 ::testing::AssertionResult IsValidBasicEvent(const rtclog::Event& event) {
55 if (!event.has_timestamp_us())
56 return ::testing::AssertionFailure() << "Event has no timestamp";
57 if (!event.has_type())
58 return ::testing::AssertionFailure() << "Event has no event type";
59 rtclog::Event_EventType type = event.type();
60 if ((type == rtclog::Event::RTP_EVENT) != event.has_rtp_packet())
61 return ::testing::AssertionFailure()
62 << "Event of type " << type << " has "
63 << (event.has_rtp_packet() ? "" : "no ") << "RTP packet";
64 if ((type == rtclog::Event::RTCP_EVENT) != event.has_rtcp_packet())
65 return ::testing::AssertionFailure()
66 << "Event of type " << type << " has "
67 << (event.has_rtcp_packet() ? "" : "no ") << "RTCP packet";
68 if ((type == rtclog::Event::DEBUG_EVENT) != event.has_debug_event())
69 return ::testing::AssertionFailure()
70 << "Event of type " << type << " has "
71 << (event.has_debug_event() ? "" : "no ") << "debug event";
72 if ((type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT) !=
73 event.has_video_receiver_config())
74 return ::testing::AssertionFailure()
75 << "Event of type " << type << " has "
76 << (event.has_video_receiver_config() ? "" : "no ")
77 << "receiver config";
78 if ((type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT) !=
79 event.has_video_sender_config())
80 return ::testing::AssertionFailure()
81 << "Event of type " << type << " has "
82 << (event.has_video_sender_config() ? "" : "no ") << "sender config";
83 if ((type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT) !=
84 event.has_audio_receiver_config()) {
85 return ::testing::AssertionFailure()
86 << "Event of type " << type << " has "
87 << (event.has_audio_receiver_config() ? "" : "no ")
88 << "audio receiver config";
89 }
90 if ((type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT) !=
91 event.has_audio_sender_config()) {
92 return ::testing::AssertionFailure()
93 << "Event of type " << type << " has "
94 << (event.has_audio_sender_config() ? "" : "no ")
95 << "audio sender config";
96 }
97 return ::testing::AssertionSuccess();
98 }
99
100 void VerifyReceiveStreamConfig(const rtclog::Event& event,
101 const VideoReceiveStream::Config& config) {
102 ASSERT_TRUE(IsValidBasicEvent(event));
103 ASSERT_EQ(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT, event.type());
104 const rtclog::VideoReceiveConfig& receiver_config =
105 event.video_receiver_config();
106 // Check SSRCs.
107 ASSERT_TRUE(receiver_config.has_remote_ssrc());
108 EXPECT_EQ(config.rtp.remote_ssrc, receiver_config.remote_ssrc());
109 ASSERT_TRUE(receiver_config.has_local_ssrc());
110 EXPECT_EQ(config.rtp.local_ssrc, receiver_config.local_ssrc());
111 // Check RTCP settings.
112 ASSERT_TRUE(receiver_config.has_rtcp_mode());
113 if (config.rtp.rtcp_mode == newapi::kRtcpCompound)
114 EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_COMPOUND,
115 receiver_config.rtcp_mode());
116 else
117 EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE,
118 receiver_config.rtcp_mode());
119 ASSERT_TRUE(receiver_config.has_receiver_reference_time_report());
120 EXPECT_EQ(config.rtp.rtcp_xr.receiver_reference_time_report,
121 receiver_config.receiver_reference_time_report());
122 ASSERT_TRUE(receiver_config.has_remb());
123 EXPECT_EQ(config.rtp.remb, receiver_config.remb());
124 // Check RTX map.
125 ASSERT_EQ(static_cast<int>(config.rtp.rtx.size()),
126 receiver_config.rtx_map_size());
127 for (const rtclog::RtxMap& rtx_map : receiver_config.rtx_map()) {
128 ASSERT_TRUE(rtx_map.has_payload_type());
129 ASSERT_TRUE(rtx_map.has_config());
130 EXPECT_EQ(1u, config.rtp.rtx.count(rtx_map.payload_type()));
131 const rtclog::RtxConfig& rtx_config = rtx_map.config();
132 const VideoReceiveStream::Config::Rtp::Rtx& rtx =
133 config.rtp.rtx.at(rtx_map.payload_type());
134 ASSERT_TRUE(rtx_config.has_rtx_ssrc());
135 ASSERT_TRUE(rtx_config.has_rtx_payload_type());
136 EXPECT_EQ(rtx.ssrc, rtx_config.rtx_ssrc());
137 EXPECT_EQ(rtx.payload_type, rtx_config.rtx_payload_type());
138 }
139 // Check header extensions.
140 ASSERT_EQ(static_cast<int>(config.rtp.extensions.size()),
141 receiver_config.header_extensions_size());
142 for (int i = 0; i < receiver_config.header_extensions_size(); i++) {
143 ASSERT_TRUE(receiver_config.header_extensions(i).has_name());
144 ASSERT_TRUE(receiver_config.header_extensions(i).has_id());
145 const std::string& name = receiver_config.header_extensions(i).name();
146 int id = receiver_config.header_extensions(i).id();
147 EXPECT_EQ(config.rtp.extensions[i].id, id);
148 EXPECT_EQ(config.rtp.extensions[i].name, name);
149 }
150 // Check decoders.
151 ASSERT_EQ(static_cast<int>(config.decoders.size()),
152 receiver_config.decoders_size());
153 for (int i = 0; i < receiver_config.decoders_size(); i++) {
154 ASSERT_TRUE(receiver_config.decoders(i).has_name());
155 ASSERT_TRUE(receiver_config.decoders(i).has_payload_type());
156 const std::string& decoder_name = receiver_config.decoders(i).name();
157 int decoder_type = receiver_config.decoders(i).payload_type();
158 EXPECT_EQ(config.decoders[i].payload_name, decoder_name);
159 EXPECT_EQ(config.decoders[i].payload_type, decoder_type);
160 }
161 }
162
163 void VerifySendStreamConfig(const rtclog::Event& event,
164 const VideoSendStream::Config& config) {
165 ASSERT_TRUE(IsValidBasicEvent(event));
166 ASSERT_EQ(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT, event.type());
167 const rtclog::VideoSendConfig& sender_config = event.video_sender_config();
168 // Check SSRCs.
169 ASSERT_EQ(static_cast<int>(config.rtp.ssrcs.size()),
170 sender_config.ssrcs_size());
171 for (int i = 0; i < sender_config.ssrcs_size(); i++) {
172 EXPECT_EQ(config.rtp.ssrcs[i], sender_config.ssrcs(i));
173 }
174 // Check header extensions.
175 ASSERT_EQ(static_cast<int>(config.rtp.extensions.size()),
176 sender_config.header_extensions_size());
177 for (int i = 0; i < sender_config.header_extensions_size(); i++) {
178 ASSERT_TRUE(sender_config.header_extensions(i).has_name());
179 ASSERT_TRUE(sender_config.header_extensions(i).has_id());
180 const std::string& name = sender_config.header_extensions(i).name();
181 int id = sender_config.header_extensions(i).id();
182 EXPECT_EQ(config.rtp.extensions[i].id, id);
183 EXPECT_EQ(config.rtp.extensions[i].name, name);
184 }
185 // Check RTX settings.
186 ASSERT_EQ(static_cast<int>(config.rtp.rtx.ssrcs.size()),
187 sender_config.rtx_ssrcs_size());
188 for (int i = 0; i < sender_config.rtx_ssrcs_size(); i++) {
189 EXPECT_EQ(config.rtp.rtx.ssrcs[i], sender_config.rtx_ssrcs(i));
190 }
191 if (sender_config.rtx_ssrcs_size() > 0) {
192 ASSERT_TRUE(sender_config.has_rtx_payload_type());
193 EXPECT_EQ(config.rtp.rtx.payload_type, sender_config.rtx_payload_type());
194 }
195 // Check CNAME.
196 ASSERT_TRUE(sender_config.has_c_name());
197 EXPECT_EQ(config.rtp.c_name, sender_config.c_name());
198 // Check encoder.
199 ASSERT_TRUE(sender_config.has_encoder());
200 ASSERT_TRUE(sender_config.encoder().has_name());
201 ASSERT_TRUE(sender_config.encoder().has_payload_type());
202 EXPECT_EQ(config.encoder_settings.payload_name,
203 sender_config.encoder().name());
204 EXPECT_EQ(config.encoder_settings.payload_type,
205 sender_config.encoder().payload_type());
206 }
207
208 void VerifyRtpEvent(const rtclog::Event& event,
209 bool incoming,
210 MediaType media_type,
211 uint8_t* header,
212 size_t header_size,
213 size_t total_size) {
214 ASSERT_TRUE(IsValidBasicEvent(event));
215 ASSERT_EQ(rtclog::Event::RTP_EVENT, event.type());
216 const rtclog::RtpPacket& rtp_packet = event.rtp_packet();
217 ASSERT_TRUE(rtp_packet.has_incoming());
218 EXPECT_EQ(incoming, rtp_packet.incoming());
219 ASSERT_TRUE(rtp_packet.has_type());
220 EXPECT_EQ(media_type, GetRuntimeMediaType(rtp_packet.type()));
221 ASSERT_TRUE(rtp_packet.has_packet_length());
222 EXPECT_EQ(total_size, rtp_packet.packet_length());
223 ASSERT_TRUE(rtp_packet.has_header());
224 ASSERT_EQ(header_size, rtp_packet.header().size());
225 for (size_t i = 0; i < header_size; i++) {
226 EXPECT_EQ(header[i], static_cast<uint8_t>(rtp_packet.header()[i]));
227 }
228 }
229
230 void VerifyRtcpEvent(const rtclog::Event& event,
231 bool incoming,
232 MediaType media_type,
233 uint8_t* packet,
234 size_t total_size) {
235 ASSERT_TRUE(IsValidBasicEvent(event));
236 ASSERT_EQ(rtclog::Event::RTCP_EVENT, event.type());
237 const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet();
238 ASSERT_TRUE(rtcp_packet.has_incoming());
239 EXPECT_EQ(incoming, rtcp_packet.incoming());
240 ASSERT_TRUE(rtcp_packet.has_type());
241 EXPECT_EQ(media_type, GetRuntimeMediaType(rtcp_packet.type()));
242 ASSERT_TRUE(rtcp_packet.has_packet_data());
243 ASSERT_EQ(total_size, rtcp_packet.packet_data().size());
244 for (size_t i = 0; i < total_size; i++) {
245 EXPECT_EQ(packet[i], static_cast<uint8_t>(rtcp_packet.packet_data()[i]));
246 }
247 }
248
249 void VerifyLogStartEvent(const rtclog::Event& event) {
250 ASSERT_TRUE(IsValidBasicEvent(event));
251 ASSERT_EQ(rtclog::Event::DEBUG_EVENT, event.type());
252 const rtclog::DebugEvent& debug_event = event.debug_event();
253 ASSERT_TRUE(debug_event.has_type());
254 EXPECT_EQ(rtclog::DebugEvent::LOG_START, debug_event.type());
255 }
256
257 void GenerateVideoReceiveConfig(VideoReceiveStream::Config* config) {
258 // Create a map from a payload type to an encoder name.
259 VideoReceiveStream::Decoder decoder;
260 decoder.payload_type = rand();
261 decoder.payload_name = (rand() % 2 ? "VP8" : "H264");
262 config->decoders.push_back(decoder);
263 // Add SSRCs for the stream.
264 config->rtp.remote_ssrc = rand();
265 config->rtp.local_ssrc = rand();
266 // Add extensions and settings for RTCP.
267 config->rtp.rtcp_mode = rand() % 2 ? newapi::kRtcpCompound
268 : newapi::kRtcpReducedSize;
269 config->rtp.rtcp_xr.receiver_reference_time_report =
270 static_cast<bool>(rand() % 2);
271 config->rtp.remb = static_cast<bool>(rand() % 2);
272 // Add a map from a payload type to a new ssrc and a new payload type for RTX.
273 VideoReceiveStream::Config::Rtp::Rtx rtx_pair;
274 rtx_pair.ssrc = rand();
275 rtx_pair.payload_type = rand();
276 config->rtp.rtx.insert(std::make_pair(rand(), rtx_pair));
277 // Add two random header extensions.
278 const char* extension_name = rand() % 2 ? RtpExtension::kTOffset
279 : RtpExtension::kVideoRotation;
280 config->rtp.extensions.push_back(RtpExtension(extension_name, rand()));
281 extension_name = rand() % 2 ? RtpExtension::kAudioLevel
282 : RtpExtension::kAbsSendTime;
283 config->rtp.extensions.push_back(RtpExtension(extension_name, rand()));
284 }
285
286 void GenerateVideoSendConfig(VideoSendStream::Config* config) {
287 // Create a map from a payload type to an encoder name.
288 config->encoder_settings.payload_type = rand();
289 config->encoder_settings.payload_name = (rand() % 2 ? "VP8" : "H264");
290 // Add SSRCs for the stream.
291 config->rtp.ssrcs.push_back(rand());
292 // Add a map from a payload type to new ssrcs and a new payload type for RTX.
293 config->rtp.rtx.ssrcs.push_back(rand());
294 config->rtp.rtx.payload_type = rand();
295 // Add a CNAME.
296 config->rtp.c_name = "some.user@some.host";
297 // Add two random header extensions.
298 const char* extension_name = rand() % 2 ? RtpExtension::kTOffset
299 : RtpExtension::kVideoRotation;
300 config->rtp.extensions.push_back(RtpExtension(extension_name, rand()));
301 extension_name = rand() % 2 ? RtpExtension::kAudioLevel
302 : RtpExtension::kAbsSendTime;
303 config->rtp.extensions.push_back(RtpExtension(extension_name, rand()));
304 }
305
306 // Test for the RtcEventLog class. Dumps some RTP packets to disk, then reads
307 // them back to see if they match.
308 void LogSessionAndReadBack(size_t rtp_count, unsigned random_seed) {
309 std::vector<std::vector<uint8_t>> rtp_packets;
310 std::vector<uint8_t> incoming_rtcp_packet;
311 std::vector<uint8_t> outgoing_rtcp_packet;
312
313 VideoReceiveStream::Config receiver_config;
314 VideoSendStream::Config sender_config;
315
316 srand(random_seed);
317
318 // Create rtp_count RTP packets containing random data.
319 const size_t rtp_header_size = 20;
320 for (size_t i = 0; i < rtp_count; i++) {
321 size_t packet_size = 1000 + rand() % 30;
322 rtp_packets.push_back(std::vector<uint8_t>());
323 rtp_packets[i].reserve(packet_size);
324 for (size_t j = 0; j < packet_size; j++) {
325 rtp_packets[i].push_back(rand());
326 }
327 }
328 // Create two RTCP packets containing random data.
329 size_t packet_size = 1000 + rand() % 30;
330 outgoing_rtcp_packet.reserve(packet_size);
331 for (size_t j = 0; j < packet_size; j++) {
332 outgoing_rtcp_packet.push_back(rand());
333 }
334 packet_size = 1000 + rand() % 30;
335 incoming_rtcp_packet.reserve(packet_size);
336 for (size_t j = 0; j < packet_size; j++) {
337 incoming_rtcp_packet.push_back(rand());
338 }
339 // Create configurations for the video streams.
340 GenerateVideoReceiveConfig(&receiver_config);
341 GenerateVideoSendConfig(&sender_config);
342
343 // Find the name of the current test, in order to use it as a temporary
344 // filename.
345 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
346 const std::string temp_filename =
347 test::OutputPath() + test_info->test_case_name() + test_info->name();
348
349 // When log_dumper goes out of scope, it causes the log file to be flushed
350 // to disk.
351 {
352 rtc::scoped_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
353 log_dumper->LogVideoReceiveStreamConfig(receiver_config);
354 log_dumper->LogVideoSendStreamConfig(sender_config);
355 size_t i = 0;
356 for (; i < rtp_count / 2; i++) {
357 log_dumper->LogRtpHeader(
358 (i % 2 == 0), // Every second packet is incoming.
359 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
360 rtp_packets[i].data(), rtp_header_size, rtp_packets[i].size());
361 }
362 log_dumper->LogRtcpPacket(false, MediaType::AUDIO,
363 outgoing_rtcp_packet.data(),
364 outgoing_rtcp_packet.size());
365 log_dumper->StartLogging(temp_filename, 10000000);
366 for (; i < rtp_count; i++) {
367 log_dumper->LogRtpHeader(
368 (i % 2 == 0), // Every second packet is incoming,
369 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
370 rtp_packets[i].data(), rtp_header_size, rtp_packets[i].size());
371 }
372 log_dumper->LogRtcpPacket(true, MediaType::VIDEO,
373 incoming_rtcp_packet.data(),
374 incoming_rtcp_packet.size());
375 }
376
377 const int config_count = 2;
378 const int rtcp_count = 2;
379 const int debug_count = 1; // Only LogStart event,
380 const int event_count = config_count + debug_count + rtcp_count + rtp_count;
381
382 // Read the generated file from disk.
383 rtclog::EventStream parsed_stream;
384
385 ASSERT_TRUE(RtcEventLog::ParseRtcEventLog(temp_filename, &parsed_stream));
386
387 // Verify the result.
388 EXPECT_EQ(event_count, parsed_stream.stream_size());
389 VerifyReceiveStreamConfig(parsed_stream.stream(0), receiver_config);
390 VerifySendStreamConfig(parsed_stream.stream(1), sender_config);
391 size_t i = 0;
392 for (; i < rtp_count / 2; i++) {
393 VerifyRtpEvent(parsed_stream.stream(config_count + i),
394 (i % 2 == 0), // Every second packet is incoming.
395 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
396 rtp_packets[i].data(), rtp_header_size,
397 rtp_packets[i].size());
398 }
399 VerifyRtcpEvent(parsed_stream.stream(config_count + rtp_count / 2),
400 false, // Outgoing RTCP packet.
401 MediaType::AUDIO, outgoing_rtcp_packet.data(),
402 outgoing_rtcp_packet.size());
403
404 VerifyLogStartEvent(parsed_stream.stream(1 + config_count + rtp_count / 2));
405 for (; i < rtp_count; i++) {
406 VerifyRtpEvent(parsed_stream.stream(2 + config_count + i),
407 (i % 2 == 0), // Every second packet is incoming.
408 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
409 rtp_packets[i].data(), rtp_header_size,
410 rtp_packets[i].size());
411 }
412 VerifyRtcpEvent(parsed_stream.stream(2 + config_count + rtp_count),
413 true, // Incoming RTCP packet.
414 MediaType::VIDEO, incoming_rtcp_packet.data(),
415 incoming_rtcp_packet.size());
416
417 // Clean up temporary file - can be pretty slow.
418 remove(temp_filename.c_str());
419 }
420
421 TEST(RtcEventLogTest, LogSessionAndReadBack) {
422 LogSessionAndReadBack(5, 321);
423 LogSessionAndReadBack(8, 3141592653u);
424 LogSessionAndReadBack(9, 2718281828u);
425 }
426
427 } // namespace webrtc
428
429 #endif // ENABLE_RTC_EVENT_LOG
OLDNEW
« no previous file with comments | « webrtc/video/rtc_event_log.proto ('k') | webrtc/webrtc.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698