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

Side by Side Diff: webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc

Issue 1316903002: Update to the neteq_rtpplay utility to support RtcEventLog input files. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Initial version Created 5 years, 3 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) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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 12 matching lines...) Expand all
23 23
24 #include "google/gflags.h" 24 #include "google/gflags.h"
25 #include "webrtc/base/checks.h" 25 #include "webrtc/base/checks.h"
26 #include "webrtc/base/scoped_ptr.h" 26 #include "webrtc/base/scoped_ptr.h"
27 #include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" 27 #include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
28 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h" 28 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
29 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" 29 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
30 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" 30 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h"
31 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h" 31 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h"
32 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" 32 #include "webrtc/modules/audio_coding/neteq/tools/packet.h"
33 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h"
33 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" 34 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"
34 #include "webrtc/modules/interface/module_common_types.h" 35 #include "webrtc/modules/interface/module_common_types.h"
35 #include "webrtc/system_wrappers/interface/trace.h" 36 #include "webrtc/system_wrappers/interface/trace.h"
36 #include "webrtc/test/testsupport/fileutils.h" 37 #include "webrtc/test/testsupport/fileutils.h"
37 #include "webrtc/typedefs.h" 38 #include "webrtc/typedefs.h"
38 39
39 using webrtc::NetEq; 40 using webrtc::NetEq;
40 using webrtc::WebRtcRTPHeader; 41 using webrtc::WebRtcRTPHeader;
41 42
42 namespace { 43 namespace {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 const bool cn_swb48_dummy = 131 const bool cn_swb48_dummy =
131 google::RegisterFlagValidator(&FLAGS_cn_swb48, &ValidatePayloadType); 132 google::RegisterFlagValidator(&FLAGS_cn_swb48, &ValidatePayloadType);
132 DEFINE_bool(codec_map, false, "Prints the mapping between RTP payload type and " 133 DEFINE_bool(codec_map, false, "Prints the mapping between RTP payload type and "
133 "codec"); 134 "codec");
134 DEFINE_string(replacement_audio_file, "", 135 DEFINE_string(replacement_audio_file, "",
135 "A PCM file that will be used to populate ""dummy"" RTP packets"); 136 "A PCM file that will be used to populate ""dummy"" RTP packets");
136 DEFINE_string(ssrc, 137 DEFINE_string(ssrc,
137 "", 138 "",
138 "Only use packets with this SSRC (decimal or hex, the latter " 139 "Only use packets with this SSRC (decimal or hex, the latter "
139 "starting with 0x)"); 140 "starting with 0x)");
141 DEFINE_bool(rtc_event_log,
142 false,
143 "Enables using a stored RtcEventLog as input "
hlundin-webrtc 2015/08/28 12:06:24 No need to break this line.
ivoc 2015/09/01 10:03:50 Fixed. The string was longer before and I forgot t
144 "file.");
140 const bool hex_ssrc_dummy = 145 const bool hex_ssrc_dummy =
141 google::RegisterFlagValidator(&FLAGS_ssrc, &ValidateSsrcValue); 146 google::RegisterFlagValidator(&FLAGS_ssrc, &ValidateSsrcValue);
142 147
143 // Maps a codec type to a printable name string. 148 // Maps a codec type to a printable name string.
144 std::string CodecName(webrtc::NetEqDecoder codec) { 149 std::string CodecName(webrtc::NetEqDecoder codec) {
145 switch (codec) { 150 switch (codec) {
146 case webrtc::kDecoderPCMu: 151 case webrtc::kDecoderPCMu:
147 return "PCM-u"; 152 return "PCM-u";
148 case webrtc::kDecoderPCMa: 153 case webrtc::kDecoderPCMa:
149 return "PCM-a"; 154 return "PCM-a";
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 if (FLAGS_codec_map) { 382 if (FLAGS_codec_map) {
378 // We have already printed the codec map. Just end the program. 383 // We have already printed the codec map. Just end the program.
379 return 0; 384 return 0;
380 } 385 }
381 // Print usage information. 386 // Print usage information.
382 std::cout << google::ProgramUsage(); 387 std::cout << google::ProgramUsage();
383 return 0; 388 return 0;
384 } 389 }
385 390
386 printf("Input file: %s\n", argv[1]); 391 printf("Input file: %s\n", argv[1]);
387 rtc::scoped_ptr<webrtc::test::RtpFileSource> file_source( 392 rtc::scoped_ptr<webrtc::test::PacketSource> file_source;
388 webrtc::test::RtpFileSource::Create(argv[1])); 393 webrtc::test::RtcEventLogSource* event_log_source = nullptr;
394 if (FLAGS_rtc_event_log) {
395 event_log_source = webrtc::test::RtcEventLogSource::Create(argv[1]);
minyue-webrtc 2015/08/28 14:50:21 Is there a way to detect the format automatically?
ivoc 2015/09/01 10:03:50 Good idea. I added this feature by checking if the
396 file_source.reset(event_log_source);
397 } else {
398 file_source.reset(webrtc::test::RtpFileSource::Create(argv[1]));
399 }
400
389 assert(file_source.get()); 401 assert(file_source.get());
390 402
391 // Check if an SSRC value was provided. 403 // Check if an SSRC value was provided.
392 if (!FLAGS_ssrc.empty()) { 404 if (!FLAGS_ssrc.empty()) {
393 uint32_t ssrc; 405 uint32_t ssrc;
394 CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed."; 406 CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed.";
395 file_source->SelectSsrc(ssrc); 407 file_source->SelectSsrc(ssrc);
396 } 408 }
397 409
398 // Check if a replacement audio file was provided, and if so, open it. 410 // Check if a replacement audio file was provided, and if so, open it.
399 bool replace_payload = false; 411 bool replace_payload = false;
400 rtc::scoped_ptr<webrtc::test::InputAudioFile> replacement_audio_file; 412 rtc::scoped_ptr<webrtc::test::InputAudioFile> replacement_audio_file;
401 if (!FLAGS_replacement_audio_file.empty()) { 413 if (!FLAGS_replacement_audio_file.empty()) {
402 replacement_audio_file.reset( 414 replacement_audio_file.reset(
403 new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file)); 415 new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file));
404 replace_payload = true; 416 replace_payload = true;
405 } 417 }
406 418
407 // Read first packet. 419 // Read first packet.
408 rtc::scoped_ptr<webrtc::test::Packet> packet(file_source->NextPacket()); 420 rtc::scoped_ptr<webrtc::test::Packet> packet(file_source->NextPacket());
409 if (!packet) { 421 if (!packet) {
410 printf( 422 printf(
411 "Warning: input file is empty, or the filters did not match any " 423 "Warning: input file is empty, or the filters did not match any "
412 "packets\n"); 424 "packets\n");
413 webrtc::Trace::ReturnTrace(); 425 webrtc::Trace::ReturnTrace();
414 return 0; 426 return 0;
415 } 427 }
416 bool packet_available = true; 428 bool packet_available = true;
429 bool output_event_available = true;
minyue-webrtc 2015/08/28 16:54:17 I think 428 and 429 are too far, move to 500 if po
ivoc 2015/09/01 10:03:50 Done.
417 430
418 // Check the sample rate. 431 // Check the sample rate.
419 int sample_rate_hz = CodecSampleRate(packet->header().payloadType); 432 int sample_rate_hz = CodecSampleRate(packet->header().payloadType);
420 if (sample_rate_hz <= 0) { 433 if (sample_rate_hz <= 0) {
421 printf("Warning: Invalid sample rate from RTP packet.\n"); 434 printf("Warning: Invalid sample rate from RTP packet.\n");
422 webrtc::Trace::ReturnTrace(); 435 webrtc::Trace::ReturnTrace();
423 return 0; 436 return 0;
424 } 437 }
425 438
426 // Open the output file now that we know the sample rate. (Rate is only needed 439 // Open the output file now that we know the sample rate. (Rate is only needed
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 int start_time_ms = packet->time_ms(); 491 int start_time_ms = packet->time_ms();
479 int time_now_ms = packet->time_ms(); 492 int time_now_ms = packet->time_ms();
480 int next_input_time_ms = time_now_ms; 493 int next_input_time_ms = time_now_ms;
481 int next_output_time_ms = time_now_ms; 494 int next_output_time_ms = time_now_ms;
482 if (time_now_ms % kOutputBlockSizeMs != 0) { 495 if (time_now_ms % kOutputBlockSizeMs != 0) {
483 // Make sure that next_output_time_ms is rounded up to the next multiple 496 // Make sure that next_output_time_ms is rounded up to the next multiple
484 // of kOutputBlockSizeMs. (Legacy bit-exactness.) 497 // of kOutputBlockSizeMs. (Legacy bit-exactness.)
485 next_output_time_ms += 498 next_output_time_ms +=
486 kOutputBlockSizeMs - time_now_ms % kOutputBlockSizeMs; 499 kOutputBlockSizeMs - time_now_ms % kOutputBlockSizeMs;
487 } 500 }
488 while (packet_available) { 501 if (FLAGS_rtc_event_log) {
502 next_output_time_ms = event_log_source->NextAudioOutputEventMs();
minyue-webrtc 2015/08/28 16:54:17 why not keeping -1 or let NextAudioOutputEventMs g
ivoc 2015/09/01 10:03:50 Keeping it at -1 would not work because later on t
503 if (next_output_time_ms == -1) {
504 output_event_available = false;
505 next_output_time_ms = INT_MAX;
506 }
507 start_time_ms = time_now_ms =
508 std::min(next_input_time_ms, next_output_time_ms);
509 }
510 while (packet_available || output_event_available) {
489 // Check if it is time to insert packet. 511 // Check if it is time to insert packet.
490 while (time_now_ms >= next_input_time_ms && packet_available) { 512 while (time_now_ms >= next_input_time_ms && packet_available) {
491 assert(packet->virtual_payload_length_bytes() > 0); 513 assert(packet->virtual_payload_length_bytes() > 0);
492 // Parse RTP header. 514 // Parse RTP header.
493 WebRtcRTPHeader rtp_header; 515 WebRtcRTPHeader rtp_header;
494 packet->ConvertHeader(&rtp_header); 516 packet->ConvertHeader(&rtp_header);
495 const uint8_t* payload_ptr = packet->payload(); 517 const uint8_t* payload_ptr = packet->payload();
496 size_t payload_len = packet->payload_length_bytes(); 518 size_t payload_len = packet->payload_length_bytes();
497 if (replace_payload) { 519 if (replace_payload) {
498 payload_len = ReplacePayload(replacement_audio_file.get(), 520 payload_len = ReplacePayload(replacement_audio_file.get(),
(...skipping 29 matching lines...) Expand all
528 << std::endl; 550 << std::endl;
529 std::cerr << " TS = " << rtp_header.header.timestamp << std::endl; 551 std::cerr << " TS = " << rtp_header.header.timestamp << std::endl;
530 } 552 }
531 } 553 }
532 554
533 // Get next packet from file. 555 // Get next packet from file.
534 webrtc::test::Packet* temp_packet = file_source->NextPacket(); 556 webrtc::test::Packet* temp_packet = file_source->NextPacket();
535 if (temp_packet) { 557 if (temp_packet) {
536 packet.reset(temp_packet); 558 packet.reset(temp_packet);
537 } else { 559 } else {
560 // Set next input time to INT_MAX to prevent the time_now_ms from
561 // becoming stuck at the final value.
562 next_input_time_ms = INT_MAX;
538 packet_available = false; 563 packet_available = false;
564 break;
hlundin-webrtc 2015/08/28 12:06:24 What are you breaking out of, and why do you have
ivoc 2015/09/01 10:03:50 This break is for the while loop on line 512, it i
539 } 565 }
540 if (replace_payload) { 566 if (replace_payload) {
hlundin-webrtc 2015/08/28 12:06:25 Did you try to run with a replacement audio file?
ivoc 2015/09/01 10:03:50 It seems like next_input_time_ms is not used at al
hlundin-webrtc 2015/09/02 08:48:51 Acknowledged.
541 // At this point |packet| contains the packet *after* |next_packet|. 567 // At this point |packet| contains the packet *after* |next_packet|.
542 // Swap Packet objects between |packet| and |next_packet|. 568 // Swap Packet objects between |packet| and |next_packet|.
543 packet.swap(next_packet); 569 packet.swap(next_packet);
544 // Swap the status indicators unless they're already the same. 570 // Swap the status indicators unless they're already the same.
545 if (packet_available != next_packet_available) { 571 if (packet_available != next_packet_available) {
546 packet_available = !packet_available; 572 packet_available = !packet_available;
547 next_packet_available = !next_packet_available; 573 next_packet_available = !next_packet_available;
548 } 574 }
549 } 575 }
550 next_input_time_ms = packet->time_ms(); 576 next_input_time_ms = packet->time_ms();
551 } 577 }
552 578
553 // Check if it is time to get output audio. 579 // Check if it is time to get output audio.
554 if (time_now_ms >= next_output_time_ms) { 580 while (time_now_ms >= next_output_time_ms && output_event_available) {
555 static const int kOutDataLen = 581 static const int kOutDataLen =
556 kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels; 582 kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels;
557 int16_t out_data[kOutDataLen]; 583 int16_t out_data[kOutDataLen];
558 int num_channels; 584 int num_channels;
559 int samples_per_channel; 585 int samples_per_channel;
560 int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel, 586 int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel,
561 &num_channels, NULL); 587 &num_channels, NULL);
562 if (error != NetEq::kOK) { 588 if (error != NetEq::kOK) {
563 std::cerr << "GetAudio returned error code " << 589 std::cerr << "GetAudio returned error code " <<
564 neteq->LastError() << std::endl; 590 neteq->LastError() << std::endl;
565 } else { 591 } else {
566 // Calculate sample rate from output size. 592 // Calculate sample rate from output size.
567 sample_rate_hz = 1000 * samples_per_channel / kOutputBlockSizeMs; 593 sample_rate_hz = 1000 * samples_per_channel / kOutputBlockSizeMs;
568 } 594 }
569 595
570 // Write to file. 596 // Write to file.
571 // TODO(hlundin): Make writing to file optional. 597 // TODO(hlundin): Make writing to file optional.
572 size_t write_len = samples_per_channel * num_channels; 598 size_t write_len = samples_per_channel * num_channels;
573 if (!output->WriteArray(out_data, write_len)) { 599 if (!output->WriteArray(out_data, write_len)) {
574 std::cerr << "Error while writing to file" << std::endl; 600 std::cerr << "Error while writing to file" << std::endl;
575 webrtc::Trace::ReturnTrace(); 601 webrtc::Trace::ReturnTrace();
576 exit(1); 602 exit(1);
577 } 603 }
578 next_output_time_ms += kOutputBlockSizeMs; 604 next_output_time_ms += kOutputBlockSizeMs;
605 if (FLAGS_rtc_event_log) {
606 next_output_time_ms = event_log_source->NextAudioOutputEventMs();
607 if (next_output_time_ms == -1) {
608 output_event_available = false;
609 // Set the next output time to INT_MAX to prevent the time_now_ms
610 // from being set to -1.
611 next_output_time_ms = INT_MAX;
612 break;
hlundin-webrtc 2015/08/28 12:06:24 Same as the break above.
ivoc 2015/09/01 10:03:50 Here the break is for the while loop on line 580,
613 }
614 } else {
615 if (!packet_available) {
616 output_event_available = false;
617 }
618 }
579 } 619 }
580 // Advance time to next event. 620 // Advance time to next event.
581 time_now_ms = std::min(next_input_time_ms, next_output_time_ms); 621 time_now_ms = std::min(next_input_time_ms, next_output_time_ms);
582 } 622 }
583
584 printf("Simulation done\n"); 623 printf("Simulation done\n");
585 printf("Produced %i ms of audio\n", time_now_ms - start_time_ms); 624 printf("Produced %i ms of audio\n", time_now_ms - start_time_ms);
586 625
587 delete neteq; 626 delete neteq;
588 webrtc::Trace::ReturnTrace(); 627 webrtc::Trace::ReturnTrace();
589 return 0; 628 return 0;
590 } 629 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698