| OLD | NEW |
| 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 |
| 11 // TODO(hlundin): The functionality in this file should be moved into one or | 11 // TODO(hlundin): The functionality in this file should be moved into one or |
| 12 // several classes. | 12 // several classes. |
| 13 | 13 |
| 14 #include <assert.h> | 14 #include <assert.h> |
| 15 #include <errno.h> | 15 #include <errno.h> |
| 16 #include <limits.h> // For ULONG_MAX returned by strtoul. | 16 #include <limits.h> // For ULONG_MAX returned by strtoul. |
| 17 #include <stdio.h> | 17 #include <stdio.h> |
| 18 #include <stdlib.h> // For strtoul. | 18 #include <stdlib.h> // For strtoul. |
| 19 | 19 |
| 20 #include <algorithm> | 20 #include <algorithm> |
| 21 #include <iostream> | 21 #include <iostream> |
| 22 #include <memory> |
| 22 #include <limits> | 23 #include <limits> |
| 23 #include <string> | 24 #include <string> |
| 24 | 25 |
| 25 #include "gflags/gflags.h" | 26 #include "gflags/gflags.h" |
| 26 #include "webrtc/base/checks.h" | 27 #include "webrtc/base/checks.h" |
| 27 #include "webrtc/base/safe_conversions.h" | 28 #include "webrtc/base/safe_conversions.h" |
| 28 #include "webrtc/base/scoped_ptr.h" | |
| 29 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" | 29 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" |
| 30 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" | 30 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" |
| 31 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" | 31 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" |
| 32 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" | 32 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" |
| 33 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h" | 33 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h" |
| 34 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" | 34 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" |
| 35 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" | 35 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" |
| 36 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" | 36 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" |
| 37 #include "webrtc/modules/include/module_common_types.h" | 37 #include "webrtc/modules/include/module_common_types.h" |
| 38 #include "webrtc/system_wrappers/include/trace.h" | 38 #include "webrtc/system_wrappers/include/trace.h" |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 if (payload_type == FLAGS_avt || payload_type == FLAGS_red) | 288 if (payload_type == FLAGS_avt || payload_type == FLAGS_red) |
| 289 return 0; | 289 return 0; |
| 290 return -1; | 290 return -1; |
| 291 } | 291 } |
| 292 | 292 |
| 293 int CodecTimestampRate(uint8_t payload_type) { | 293 int CodecTimestampRate(uint8_t payload_type) { |
| 294 return (payload_type == FLAGS_g722) ? 8000 : CodecSampleRate(payload_type); | 294 return (payload_type == FLAGS_g722) ? 8000 : CodecSampleRate(payload_type); |
| 295 } | 295 } |
| 296 | 296 |
| 297 size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, | 297 size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, |
| 298 rtc::scoped_ptr<int16_t[]>* replacement_audio, | 298 std::unique_ptr<int16_t[]>* replacement_audio, |
| 299 rtc::scoped_ptr<uint8_t[]>* payload, | 299 std::unique_ptr<uint8_t[]>* payload, |
| 300 size_t* payload_mem_size_bytes, | 300 size_t* payload_mem_size_bytes, |
| 301 size_t* frame_size_samples, | 301 size_t* frame_size_samples, |
| 302 WebRtcRTPHeader* rtp_header, | 302 WebRtcRTPHeader* rtp_header, |
| 303 const webrtc::test::Packet* next_packet) { | 303 const webrtc::test::Packet* next_packet) { |
| 304 size_t payload_len = 0; | 304 size_t payload_len = 0; |
| 305 // Check for CNG. | 305 // Check for CNG. |
| 306 if (IsComfortNoise(rtp_header->header.payloadType)) { | 306 if (IsComfortNoise(rtp_header->header.payloadType)) { |
| 307 // If CNG, simply insert a zero-energy one-byte payload. | 307 // If CNG, simply insert a zero-energy one-byte payload. |
| 308 if (*payload_mem_size_bytes < 1) { | 308 if (*payload_mem_size_bytes < 1) { |
| 309 (*payload).reset(new uint8_t[1]); | 309 (*payload).reset(new uint8_t[1]); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 return 0; | 404 return 0; |
| 405 } | 405 } |
| 406 // Print usage information. | 406 // Print usage information. |
| 407 std::cout << google::ProgramUsage(); | 407 std::cout << google::ProgramUsage(); |
| 408 return 0; | 408 return 0; |
| 409 } | 409 } |
| 410 | 410 |
| 411 printf("Input file: %s\n", argv[1]); | 411 printf("Input file: %s\n", argv[1]); |
| 412 | 412 |
| 413 bool is_rtp_dump = false; | 413 bool is_rtp_dump = false; |
| 414 rtc::scoped_ptr<webrtc::test::PacketSource> file_source; | 414 std::unique_ptr<webrtc::test::PacketSource> file_source; |
| 415 webrtc::test::RtcEventLogSource* event_log_source = nullptr; | 415 webrtc::test::RtcEventLogSource* event_log_source = nullptr; |
| 416 if (webrtc::test::RtpFileSource::ValidRtpDump(argv[1]) || | 416 if (webrtc::test::RtpFileSource::ValidRtpDump(argv[1]) || |
| 417 webrtc::test::RtpFileSource::ValidPcap(argv[1])) { | 417 webrtc::test::RtpFileSource::ValidPcap(argv[1])) { |
| 418 is_rtp_dump = true; | 418 is_rtp_dump = true; |
| 419 file_source.reset(webrtc::test::RtpFileSource::Create(argv[1])); | 419 file_source.reset(webrtc::test::RtpFileSource::Create(argv[1])); |
| 420 } else { | 420 } else { |
| 421 event_log_source = webrtc::test::RtcEventLogSource::Create(argv[1]); | 421 event_log_source = webrtc::test::RtcEventLogSource::Create(argv[1]); |
| 422 file_source.reset(event_log_source); | 422 file_source.reset(event_log_source); |
| 423 } | 423 } |
| 424 | 424 |
| 425 assert(file_source.get()); | 425 assert(file_source.get()); |
| 426 | 426 |
| 427 // Check if an SSRC value was provided. | 427 // Check if an SSRC value was provided. |
| 428 if (!FLAGS_ssrc.empty()) { | 428 if (!FLAGS_ssrc.empty()) { |
| 429 uint32_t ssrc; | 429 uint32_t ssrc; |
| 430 RTC_CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed."; | 430 RTC_CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed."; |
| 431 file_source->SelectSsrc(ssrc); | 431 file_source->SelectSsrc(ssrc); |
| 432 } | 432 } |
| 433 | 433 |
| 434 // Check if a replacement audio file was provided, and if so, open it. | 434 // Check if a replacement audio file was provided, and if so, open it. |
| 435 bool replace_payload = false; | 435 bool replace_payload = false; |
| 436 rtc::scoped_ptr<webrtc::test::InputAudioFile> replacement_audio_file; | 436 std::unique_ptr<webrtc::test::InputAudioFile> replacement_audio_file; |
| 437 if (!FLAGS_replacement_audio_file.empty()) { | 437 if (!FLAGS_replacement_audio_file.empty()) { |
| 438 replacement_audio_file.reset( | 438 replacement_audio_file.reset( |
| 439 new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file)); | 439 new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file)); |
| 440 replace_payload = true; | 440 replace_payload = true; |
| 441 } | 441 } |
| 442 | 442 |
| 443 // Read first packet. | 443 // Read first packet. |
| 444 rtc::scoped_ptr<webrtc::test::Packet> packet(file_source->NextPacket()); | 444 std::unique_ptr<webrtc::test::Packet> packet(file_source->NextPacket()); |
| 445 if (!packet) { | 445 if (!packet) { |
| 446 printf( | 446 printf( |
| 447 "Warning: input file is empty, or the filters did not match any " | 447 "Warning: input file is empty, or the filters did not match any " |
| 448 "packets\n"); | 448 "packets\n"); |
| 449 webrtc::Trace::ReturnTrace(); | 449 webrtc::Trace::ReturnTrace(); |
| 450 return 0; | 450 return 0; |
| 451 } | 451 } |
| 452 if (packet->payload_length_bytes() == 0 && !replace_payload) { | 452 if (packet->payload_length_bytes() == 0 && !replace_payload) { |
| 453 std::cerr << "Warning: input file contains header-only packets, but no " | 453 std::cerr << "Warning: input file contains header-only packets, but no " |
| 454 << "replacement file is specified." << std::endl; | 454 << "replacement file is specified." << std::endl; |
| 455 webrtc::Trace::ReturnTrace(); | 455 webrtc::Trace::ReturnTrace(); |
| 456 return -1; | 456 return -1; |
| 457 } | 457 } |
| 458 | 458 |
| 459 // Check the sample rate. | 459 // Check the sample rate. |
| 460 int sample_rate_hz = CodecSampleRate(packet->header().payloadType); | 460 int sample_rate_hz = CodecSampleRate(packet->header().payloadType); |
| 461 if (sample_rate_hz <= 0) { | 461 if (sample_rate_hz <= 0) { |
| 462 printf("Warning: Invalid sample rate from RTP packet.\n"); | 462 printf("Warning: Invalid sample rate from RTP packet.\n"); |
| 463 webrtc::Trace::ReturnTrace(); | 463 webrtc::Trace::ReturnTrace(); |
| 464 return 0; | 464 return 0; |
| 465 } | 465 } |
| 466 | 466 |
| 467 // Open the output file now that we know the sample rate. (Rate is only needed | 467 // Open the output file now that we know the sample rate. (Rate is only needed |
| 468 // for wav files.) | 468 // for wav files.) |
| 469 // Check output file type. | 469 // Check output file type. |
| 470 std::string output_file_name = argv[2]; | 470 std::string output_file_name = argv[2]; |
| 471 rtc::scoped_ptr<webrtc::test::AudioSink> output; | 471 std::unique_ptr<webrtc::test::AudioSink> output; |
| 472 if (output_file_name.size() >= 4 && | 472 if (output_file_name.size() >= 4 && |
| 473 output_file_name.substr(output_file_name.size() - 4) == ".wav") { | 473 output_file_name.substr(output_file_name.size() - 4) == ".wav") { |
| 474 // Open a wav file. | 474 // Open a wav file. |
| 475 output.reset( | 475 output.reset( |
| 476 new webrtc::test::OutputWavFile(output_file_name, sample_rate_hz)); | 476 new webrtc::test::OutputWavFile(output_file_name, sample_rate_hz)); |
| 477 } else { | 477 } else { |
| 478 // Open a pcm file. | 478 // Open a pcm file. |
| 479 output.reset(new webrtc::test::OutputAudioFile(output_file_name)); | 479 output.reset(new webrtc::test::OutputAudioFile(output_file_name)); |
| 480 } | 480 } |
| 481 | 481 |
| 482 std::cout << "Output file: " << argv[2] << std::endl; | 482 std::cout << "Output file: " << argv[2] << std::endl; |
| 483 | 483 |
| 484 // Enable tracing. | 484 // Enable tracing. |
| 485 webrtc::Trace::CreateTrace(); | 485 webrtc::Trace::CreateTrace(); |
| 486 webrtc::Trace::SetTraceFile((webrtc::test::OutputPath() + | 486 webrtc::Trace::SetTraceFile((webrtc::test::OutputPath() + |
| 487 "neteq_trace.txt").c_str()); | 487 "neteq_trace.txt").c_str()); |
| 488 webrtc::Trace::set_level_filter(webrtc::kTraceAll); | 488 webrtc::Trace::set_level_filter(webrtc::kTraceAll); |
| 489 | 489 |
| 490 // Initialize NetEq instance. | 490 // Initialize NetEq instance. |
| 491 NetEq::Config config; | 491 NetEq::Config config; |
| 492 config.sample_rate_hz = sample_rate_hz; | 492 config.sample_rate_hz = sample_rate_hz; |
| 493 NetEq* neteq = NetEq::Create(config); | 493 NetEq* neteq = NetEq::Create(config); |
| 494 RegisterPayloadTypes(neteq); | 494 RegisterPayloadTypes(neteq); |
| 495 | 495 |
| 496 | 496 |
| 497 // Set up variables for audio replacement if needed. | 497 // Set up variables for audio replacement if needed. |
| 498 rtc::scoped_ptr<webrtc::test::Packet> next_packet; | 498 std::unique_ptr<webrtc::test::Packet> next_packet; |
| 499 bool next_packet_available = false; | 499 bool next_packet_available = false; |
| 500 size_t input_frame_size_timestamps = 0; | 500 size_t input_frame_size_timestamps = 0; |
| 501 rtc::scoped_ptr<int16_t[]> replacement_audio; | 501 std::unique_ptr<int16_t[]> replacement_audio; |
| 502 rtc::scoped_ptr<uint8_t[]> payload; | 502 std::unique_ptr<uint8_t[]> payload; |
| 503 size_t payload_mem_size_bytes = 0; | 503 size_t payload_mem_size_bytes = 0; |
| 504 if (replace_payload) { | 504 if (replace_payload) { |
| 505 // Initially assume that the frame size is 30 ms at the initial sample rate. | 505 // Initially assume that the frame size is 30 ms at the initial sample rate. |
| 506 // This value will be replaced with the correct one as soon as two | 506 // This value will be replaced with the correct one as soon as two |
| 507 // consecutive packets are found. | 507 // consecutive packets are found. |
| 508 input_frame_size_timestamps = 30 * sample_rate_hz / 1000; | 508 input_frame_size_timestamps = 30 * sample_rate_hz / 1000; |
| 509 replacement_audio.reset(new int16_t[input_frame_size_timestamps]); | 509 replacement_audio.reset(new int16_t[input_frame_size_timestamps]); |
| 510 payload_mem_size_bytes = 2 * input_frame_size_timestamps; | 510 payload_mem_size_bytes = 2 * input_frame_size_timestamps; |
| 511 payload.reset(new uint8_t[payload_mem_size_bytes]); | 511 payload.reset(new uint8_t[payload_mem_size_bytes]); |
| 512 next_packet.reset(file_source->NextPacket()); | 512 next_packet.reset(file_source->NextPacket()); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 } | 642 } |
| 643 } | 643 } |
| 644 printf("Simulation done\n"); | 644 printf("Simulation done\n"); |
| 645 printf("Produced %i ms of audio\n", | 645 printf("Produced %i ms of audio\n", |
| 646 static_cast<int>(time_now_ms - start_time_ms)); | 646 static_cast<int>(time_now_ms - start_time_ms)); |
| 647 | 647 |
| 648 delete neteq; | 648 delete neteq; |
| 649 webrtc::Trace::ReturnTrace(); | 649 webrtc::Trace::ReturnTrace(); |
| 650 return 0; | 650 return 0; |
| 651 } | 651 } |
| OLD | NEW |