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

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

Issue 1411673003: Added protobuf message for loss-based BWE events, and wired it up to the send side bandwidth estima… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Logging for loss based BWE Created 5 years, 2 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
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 268 }
269 269
270 void VerifyPlayoutEvent(const rtclog::Event& event, uint32_t ssrc) { 270 void VerifyPlayoutEvent(const rtclog::Event& event, uint32_t ssrc) {
271 ASSERT_TRUE(IsValidBasicEvent(event)); 271 ASSERT_TRUE(IsValidBasicEvent(event));
272 ASSERT_EQ(rtclog::Event::AUDIO_PLAYOUT_EVENT, event.type()); 272 ASSERT_EQ(rtclog::Event::AUDIO_PLAYOUT_EVENT, event.type());
273 const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event(); 273 const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
274 ASSERT_TRUE(playout_event.has_local_ssrc()); 274 ASSERT_TRUE(playout_event.has_local_ssrc());
275 EXPECT_EQ(ssrc, playout_event.local_ssrc()); 275 EXPECT_EQ(ssrc, playout_event.local_ssrc());
276 } 276 }
277 277
278 void VerifyBweLossEvent(const rtclog::Event& event,
279 int32_t bitrate,
280 uint8_t fraction_loss,
281 int32_t total_packets) {
282 ASSERT_TRUE(IsValidBasicEvent(event));
283 ASSERT_EQ(rtclog::Event::BWE_PACKET_LOSS_EVENT, event.type());
284 const rtclog::BwePacketLossEvent& bwe_event = event.bwe_packet_loss_event();
285 ASSERT_TRUE(bwe_event.has_bitrate());
286 EXPECT_EQ(bitrate, bwe_event.bitrate());
287 ASSERT_TRUE(bwe_event.has_fraction_loss());
288 EXPECT_EQ(fraction_loss, bwe_event.fraction_loss());
289 ASSERT_TRUE(bwe_event.has_total_packets());
290 EXPECT_EQ(total_packets, bwe_event.total_packets());
291 }
292
278 void VerifyLogStartEvent(const rtclog::Event& event) { 293 void VerifyLogStartEvent(const rtclog::Event& event) {
279 ASSERT_TRUE(IsValidBasicEvent(event)); 294 ASSERT_TRUE(IsValidBasicEvent(event));
280 EXPECT_EQ(rtclog::Event::LOG_START, event.type()); 295 EXPECT_EQ(rtclog::Event::LOG_START, event.type());
281 } 296 }
282 297
283 /* 298 /*
284 * Bit number i of extension_bitvector is set to indicate the 299 * Bit number i of extension_bitvector is set to indicate the
285 * presence of extension number i from kExtensionTypes / kExtensionNames. 300 * presence of extension number i from kExtensionTypes / kExtensionNames.
286 * The least significant bit extension_bitvector has number 0. 301 * The least significant bit extension_bitvector has number 0.
287 */ 302 */
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 RtpExtension(kExtensionNames[i], rand())); 405 RtpExtension(kExtensionNames[i], rand()));
391 } 406 }
392 } 407 }
393 } 408 }
394 409
395 // Test for the RtcEventLog class. Dumps some RTP packets to disk, then reads 410 // Test for the RtcEventLog class. Dumps some RTP packets to disk, then reads
396 // them back to see if they match. 411 // them back to see if they match.
397 void LogSessionAndReadBack(size_t rtp_count, 412 void LogSessionAndReadBack(size_t rtp_count,
398 size_t rtcp_count, 413 size_t rtcp_count,
399 size_t playout_count, 414 size_t playout_count,
415 size_t bwe_loss_count,
400 uint32_t extensions_bitvector, 416 uint32_t extensions_bitvector,
401 uint32_t csrcs_count, 417 uint32_t csrcs_count,
402 unsigned random_seed) { 418 unsigned random_seed) {
403 ASSERT_LE(rtcp_count, rtp_count); 419 ASSERT_LE(rtcp_count, rtp_count);
404 ASSERT_LE(playout_count, rtp_count); 420 ASSERT_LE(playout_count, rtp_count);
421 ASSERT_LE(bwe_loss_count, rtp_count);
405 std::vector<rtc::Buffer> rtp_packets; 422 std::vector<rtc::Buffer> rtp_packets;
406 std::vector<rtc::Buffer> rtcp_packets; 423 std::vector<rtc::Buffer> rtcp_packets;
407 std::vector<size_t> rtp_header_sizes; 424 std::vector<size_t> rtp_header_sizes;
408 std::vector<uint32_t> playout_ssrcs; 425 std::vector<uint32_t> playout_ssrcs;
426 std::vector<std::pair<int32_t, uint8_t> > bwe_loss_updates;
409 427
410 VideoReceiveStream::Config receiver_config(nullptr); 428 VideoReceiveStream::Config receiver_config(nullptr);
411 VideoSendStream::Config sender_config(nullptr); 429 VideoSendStream::Config sender_config(nullptr);
412 430
413 srand(random_seed); 431 srand(random_seed);
414 432
415 // Create rtp_count RTP packets containing random data. 433 // Create rtp_count RTP packets containing random data.
416 for (size_t i = 0; i < rtp_count; i++) { 434 for (size_t i = 0; i < rtp_count; i++) {
417 size_t packet_size = 1000 + rand() % 64; 435 size_t packet_size = 1000 + rand() % 64;
418 rtp_packets.push_back(rtc::Buffer(packet_size)); 436 rtp_packets.push_back(rtc::Buffer(packet_size));
419 size_t header_size = GenerateRtpPacket(extensions_bitvector, csrcs_count, 437 size_t header_size = GenerateRtpPacket(extensions_bitvector, csrcs_count,
420 rtp_packets[i].data(), packet_size); 438 rtp_packets[i].data(), packet_size);
421 rtp_header_sizes.push_back(header_size); 439 rtp_header_sizes.push_back(header_size);
422 } 440 }
423 // Create rtcp_count RTCP packets containing random data. 441 // Create rtcp_count RTCP packets containing random data.
424 for (size_t i = 0; i < rtcp_count; i++) { 442 for (size_t i = 0; i < rtcp_count; i++) {
425 size_t packet_size = 1000 + rand() % 64; 443 size_t packet_size = 1000 + rand() % 64;
426 rtcp_packets.push_back(rtc::Buffer(packet_size)); 444 rtcp_packets.push_back(rtc::Buffer(packet_size));
427 GenerateRtcpPacket(rtcp_packets[i].data(), packet_size); 445 GenerateRtcpPacket(rtcp_packets[i].data(), packet_size);
428 } 446 }
429 // Create playout_count random SSRCs to use when logging AudioPlayout events. 447 // Create playout_count random SSRCs to use when logging AudioPlayout events.
430 for (size_t i = 0; i < playout_count; i++) { 448 for (size_t i = 0; i < playout_count; i++) {
431 playout_ssrcs.push_back(static_cast<uint32_t>(rand())); 449 playout_ssrcs.push_back(static_cast<uint32_t>(rand()));
432 } 450 }
451 // Create bwe_loss_count random bitrate updates for BwePacketLoss.
452 for (size_t i = 0; i < bwe_loss_count; i++) {
ivoc 2015/10/19 16:03:38 why not just make i an int? I don't see any compel
terelius 2015/10/26 17:40:18 No, there is no strong reason for doing it either
stefan-webrtc 2015/10/28 16:03:18 Chromium style is more explicit when it comes to s
terelius 2015/10/30 10:51:40 Acknowledged.
453 bwe_loss_updates.push_back(std::pair<int32_t, uint8_t>(rand(), rand()));
454 }
433 // Create configurations for the video streams. 455 // Create configurations for the video streams.
434 GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config); 456 GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config);
435 GenerateVideoSendConfig(extensions_bitvector, &sender_config); 457 GenerateVideoSendConfig(extensions_bitvector, &sender_config);
436 const int config_count = 2; 458 const int config_count = 2;
437 459
438 // Find the name of the current test, in order to use it as a temporary 460 // Find the name of the current test, in order to use it as a temporary
439 // filename. 461 // filename.
440 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); 462 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
441 const std::string temp_filename = 463 const std::string temp_filename =
442 test::OutputPath() + test_info->test_case_name() + test_info->name(); 464 test::OutputPath() + test_info->test_case_name() + test_info->name();
443 465
444 // When log_dumper goes out of scope, it causes the log file to be flushed 466 // When log_dumper goes out of scope, it causes the log file to be flushed
445 // to disk. 467 // to disk.
446 { 468 {
447 rtc::scoped_ptr<RtcEventLog> log_dumper(RtcEventLog::Create()); 469 rtc::scoped_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
448 log_dumper->LogVideoReceiveStreamConfig(receiver_config); 470 log_dumper->LogVideoReceiveStreamConfig(receiver_config);
449 log_dumper->LogVideoSendStreamConfig(sender_config); 471 log_dumper->LogVideoSendStreamConfig(sender_config);
450 size_t rtcp_index = 1, playout_index = 1; 472 size_t rtcp_index = 1, playout_index = 1, bwe_loss_index = 1;
stefan-webrtc 2015/10/19 08:43:22 Personally, I prefer to have one variable per line
terelius 2015/10/26 17:40:18 Done.
451 for (size_t i = 1; i <= rtp_count; i++) { 473 for (size_t i = 1; i <= rtp_count; i++) {
452 log_dumper->LogRtpHeader( 474 log_dumper->LogRtpHeader(
453 (i % 2 == 0), // Every second packet is incoming. 475 (i % 2 == 0), // Every second packet is incoming.
454 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO, 476 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
455 rtp_packets[i - 1].data(), rtp_packets[i - 1].size()); 477 rtp_packets[i - 1].data(), rtp_packets[i - 1].size());
456 if (i * rtcp_count >= rtcp_index * rtp_count) { 478 if (i * rtcp_count >= rtcp_index * rtp_count) {
457 log_dumper->LogRtcpPacket( 479 log_dumper->LogRtcpPacket(
458 rtcp_index % 2 == 0, // Every second packet is incoming 480 rtcp_index % 2 == 0, // Every second packet is incoming
459 rtcp_index % 3 == 0 ? MediaType::AUDIO : MediaType::VIDEO, 481 rtcp_index % 3 == 0 ? MediaType::AUDIO : MediaType::VIDEO,
460 rtcp_packets[rtcp_index - 1].data(), 482 rtcp_packets[rtcp_index - 1].data(),
461 rtcp_packets[rtcp_index - 1].size()); 483 rtcp_packets[rtcp_index - 1].size());
462 rtcp_index++; 484 rtcp_index++;
463 } 485 }
464 if (i * playout_count >= playout_index * rtp_count) { 486 if (i * playout_count >= playout_index * rtp_count) {
465 log_dumper->LogAudioPlayout(playout_ssrcs[playout_index - 1]); 487 log_dumper->LogAudioPlayout(playout_ssrcs[playout_index - 1]);
466 playout_index++; 488 playout_index++;
467 } 489 }
490 if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
491 log_dumper->LogBwePacketLossEvent(
492 bwe_loss_updates[bwe_loss_index - 1].first,
493 bwe_loss_updates[bwe_loss_index - 1].second, i);
494 bwe_loss_index++;
495 }
468 if (i == rtp_count / 2) { 496 if (i == rtp_count / 2) {
469 log_dumper->StartLogging(temp_filename, 10000000); 497 log_dumper->StartLogging(temp_filename, 10000000);
470 } 498 }
471 } 499 }
472 } 500 }
473 501
474 // Read the generated file from disk. 502 // Read the generated file from disk.
475 rtclog::EventStream parsed_stream; 503 rtclog::EventStream parsed_stream;
476 504
477 ASSERT_TRUE(RtcEventLog::ParseRtcEventLog(temp_filename, &parsed_stream)); 505 ASSERT_TRUE(RtcEventLog::ParseRtcEventLog(temp_filename, &parsed_stream));
478 506
479 // Verify the result. 507 // Verify the result.
480 const int event_count = 508 const int event_count = config_count + playout_count + bwe_loss_count +
481 config_count + playout_count + rtcp_count + rtp_count + 1; 509 rtcp_count + rtp_count + 1;
482 EXPECT_EQ(event_count, parsed_stream.stream_size()); 510 EXPECT_EQ(event_count, parsed_stream.stream_size());
483 VerifyReceiveStreamConfig(parsed_stream.stream(0), receiver_config); 511 VerifyReceiveStreamConfig(parsed_stream.stream(0), receiver_config);
484 VerifySendStreamConfig(parsed_stream.stream(1), sender_config); 512 VerifySendStreamConfig(parsed_stream.stream(1), sender_config);
485 size_t event_index = config_count, rtcp_index = 1, playout_index = 1; 513 size_t event_index = config_count, rtcp_index = 1, playout_index = 1,
514 bwe_loss_index = 1;
486 for (size_t i = 1; i <= rtp_count; i++) { 515 for (size_t i = 1; i <= rtp_count; i++) {
487 VerifyRtpEvent(parsed_stream.stream(event_index), 516 VerifyRtpEvent(parsed_stream.stream(event_index),
488 (i % 2 == 0), // Every second packet is incoming. 517 (i % 2 == 0), // Every second packet is incoming.
489 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO, 518 (i % 3 == 0) ? MediaType::AUDIO : MediaType::VIDEO,
490 rtp_packets[i - 1].data(), rtp_header_sizes[i - 1], 519 rtp_packets[i - 1].data(), rtp_header_sizes[i - 1],
491 rtp_packets[i - 1].size()); 520 rtp_packets[i - 1].size());
492 event_index++; 521 event_index++;
493 if (i * rtcp_count >= rtcp_index * rtp_count) { 522 if (i * rtcp_count >= rtcp_index * rtp_count) {
494 VerifyRtcpEvent(parsed_stream.stream(event_index), 523 VerifyRtcpEvent(parsed_stream.stream(event_index),
495 rtcp_index % 2 == 0, // Every second packet is incoming. 524 rtcp_index % 2 == 0, // Every second packet is incoming.
496 rtcp_index % 3 == 0 ? MediaType::AUDIO : MediaType::VIDEO, 525 rtcp_index % 3 == 0 ? MediaType::AUDIO : MediaType::VIDEO,
497 rtcp_packets[rtcp_index - 1].data(), 526 rtcp_packets[rtcp_index - 1].data(),
498 rtcp_packets[rtcp_index - 1].size()); 527 rtcp_packets[rtcp_index - 1].size());
499 event_index++; 528 event_index++;
500 rtcp_index++; 529 rtcp_index++;
501 } 530 }
502 if (i * playout_count >= playout_index * rtp_count) { 531 if (i * playout_count >= playout_index * rtp_count) {
503 VerifyPlayoutEvent(parsed_stream.stream(event_index), 532 VerifyPlayoutEvent(parsed_stream.stream(event_index),
504 playout_ssrcs[playout_index - 1]); 533 playout_ssrcs[playout_index - 1]);
505 event_index++; 534 event_index++;
506 playout_index++; 535 playout_index++;
507 } 536 }
537 if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
538 VerifyBweLossEvent(parsed_stream.stream(event_index),
539 bwe_loss_updates[bwe_loss_index - 1].first,
540 bwe_loss_updates[bwe_loss_index - 1].second, i);
541 event_index++;
542 bwe_loss_index++;
543 }
508 if (i == rtp_count / 2) { 544 if (i == rtp_count / 2) {
509 VerifyLogStartEvent(parsed_stream.stream(event_index)); 545 VerifyLogStartEvent(parsed_stream.stream(event_index));
510 event_index++; 546 event_index++;
511 } 547 }
512 } 548 }
513 549
514 // Clean up temporary file - can be pretty slow. 550 // Clean up temporary file - can be pretty slow.
515 remove(temp_filename.c_str()); 551 remove(temp_filename.c_str());
516 } 552 }
517 553
518 TEST(RtcEventLogTest, LogSessionAndReadBack) { 554 TEST(RtcEventLogTest, LogSessionAndReadBack) {
519 // Log 5 RTP, 2 RTCP, and 0 playout events with no header extensions or CSRCS. 555 // Log 5 RTP, 2 RTCP, 0 playout events and 0 BWE events
520 LogSessionAndReadBack(5, 2, 0, 0, 0, 321); 556 // with no header extensions or CSRCS.
557 LogSessionAndReadBack(5, 2, 0, 0, 0, 0, 321);
521 558
522 // Enable AbsSendTime and TransportSequenceNumbers 559 // Enable AbsSendTime and TransportSequenceNumbers.
523 uint32_t extensions = 0; 560 uint32_t extensions = 0;
524 for (uint32_t i = 0; i < kNumExtensions; i++) { 561 for (uint32_t i = 0; i < kNumExtensions; i++) {
525 if (kExtensionTypes[i] == RTPExtensionType::kRtpExtensionAbsoluteSendTime || 562 if (kExtensionTypes[i] == RTPExtensionType::kRtpExtensionAbsoluteSendTime ||
526 kExtensionTypes[i] == 563 kExtensionTypes[i] ==
527 RTPExtensionType::kRtpExtensionTransportSequenceNumber) { 564 RTPExtensionType::kRtpExtensionTransportSequenceNumber) {
528 extensions |= 1u << i; 565 extensions |= 1u << i;
529 } 566 }
530 } 567 }
531 LogSessionAndReadBack(8, 2, 0, extensions, 0, 3141592653u); 568 LogSessionAndReadBack(8, 2, 0, 0, extensions, 0, 3141592653u);
532 569
533 extensions = (1u << kNumExtensions) - 1; // Enable all header extensions 570 extensions = (1u << kNumExtensions) - 1; // Enable all header extensions.
534 LogSessionAndReadBack(9, 2, 3, extensions, 2, 2718281828u); 571 LogSessionAndReadBack(9, 2, 3, 2, extensions, 2, 2718281828u);
535 572
536 // Try all combinations of header extensions and up to 2 CSRCS. 573 // Try all combinations of header extensions and up to 2 CSRCS.
537 for (extensions = 0; extensions < (1u << kNumExtensions); extensions++) { 574 for (extensions = 0; extensions < (1u << kNumExtensions); extensions++) {
538 for (uint32_t csrcs_count = 0; csrcs_count < 3; csrcs_count++) { 575 for (uint32_t csrcs_count = 0; csrcs_count < 3; csrcs_count++) {
539 LogSessionAndReadBack(5 + extensions, // Number of RTP packets. 576 LogSessionAndReadBack(5 + extensions, // Number of RTP packets.
540 2 + csrcs_count, // Number of RTCP packets. 577 2 + csrcs_count, // Number of RTCP packets.
541 3 + csrcs_count, // Number of playout events 578 3 + csrcs_count, // Number of playout events.
542 extensions, // Bit vector choosing extensions 579 1 + csrcs_count, // Number of BWE loss events.
543 csrcs_count, // Number of contributing sources 580 extensions, // Bit vector choosing extensions.
581 csrcs_count, // Number of contributing sources.
544 rand()); 582 rand());
545 } 583 }
546 } 584 }
547 } 585 }
548 586
549 } // namespace webrtc 587 } // namespace webrtc
550 588
551 #endif // ENABLE_RTC_EVENT_LOG 589 #endif // ENABLE_RTC_EVENT_LOG
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698