From 1c8391205e9caf05337dbbe071944b7ba11a6cec Mon Sep 17 00:00:00 2001 From: "henrik.lundin@webrtc.org" Date: Mon, 11 Aug 2014 12:29:38 +0000 Subject: [PATCH] Use test::Packet test::PacketSource classes in neteq_rtpplay This change replaces the old NETEQTEST_RTPpacket and NETEQTEST_DummyRTPpacket with the new test::Packet class. Note that the Packet class automatically handles "dummy" packets (i.e., packets for which only the header and a length field was stored to file) automatically. There is no need to explicitly signal this to the application any longer. The RTP input file is now handled as a test::PacketSource object. Also adding a new ConvertHeader method to the Packet class. This is needed to extract the header information as an alternative data type. Finally, some dead code was deleted from rtp_analyze.cc (unrelated to the reset of this change). BUG=2692 R=minyue@webrtc.org Review URL: https://webrtc-codereview.appspot.com/21139004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6862 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../audio_coding/neteq/neteq_tests.gypi | 1 - .../audio_coding/neteq/tools/neteq_rtpplay.cc | 168 ++++++++---------- .../audio_coding/neteq/tools/packet.cc | 12 ++ .../modules/audio_coding/neteq/tools/packet.h | 5 + .../audio_coding/neteq/tools/rtp_analyze.cc | 6 - 5 files changed, 96 insertions(+), 96 deletions(-) diff --git a/webrtc/modules/audio_coding/neteq/neteq_tests.gypi b/webrtc/modules/audio_coding/neteq/neteq_tests.gypi index 97d835f186..d134dcd49d 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_tests.gypi +++ b/webrtc/modules/audio_coding/neteq/neteq_tests.gypi @@ -13,7 +13,6 @@ 'type': 'executable', 'dependencies': [ 'neteq', - 'neteq_test_tools', 'neteq_unittest_tools', 'PCM16B', '<(webrtc_root)/test/test.gyp:test_support_main', diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc index 3e3540a8bc..e144ba72a0 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc @@ -21,9 +21,9 @@ #include "google/gflags.h" #include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/interface/neteq.h" -#include "webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h" -#include "webrtc/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h" #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" +#include "webrtc/modules/audio_coding/neteq/tools/packet.h" +#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/trace.h" @@ -92,8 +92,6 @@ static const bool cn_swb48_dummy = google::RegisterFlagValidator(&FLAGS_cn_swb48, &ValidatePayloadType); DEFINE_bool(codec_map, false, "Prints the mapping between RTP payload type and " "codec"); -DEFINE_bool(dummy_rtp, false, "The input file contains ""dummy"" RTP data, " - "i.e., only headers"); DEFINE_string(replacement_audio_file, "", "A PCM file that will be used to populate ""dummy"" RTP packets"); @@ -107,7 +105,7 @@ size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, size_t* payload_mem_size_bytes, size_t* frame_size_samples, WebRtcRTPHeader* rtp_header, - NETEQTEST_RTPpacket* next_rtp); + const webrtc::test::Packet* next_packet); int CodecSampleRate(uint8_t payload_type); int CodecTimestampRate(uint8_t payload_type); bool IsComfortNosie(uint8_t payload_type); @@ -139,15 +137,13 @@ int main(int argc, char* argv[]) { return 0; } - FILE* in_file = fopen(argv[1], "rb"); - if (!in_file) { - std::cerr << "Cannot open input file " << argv[1] << std::endl; - exit(1); - } - std::cout << "Input file: " << argv[1] << std::endl; + printf("Input file: %s\n", argv[1]); + webrtc::scoped_ptr file_source( + webrtc::test::RtpFileSource::Create(argv[1])); + assert(file_source.get()); FILE* out_file = fopen(argv[2], "wb"); - if (!in_file) { + if (!out_file) { std::cerr << "Cannot open output file " << argv[2] << std::endl; exit(1); } @@ -162,12 +158,6 @@ int main(int argc, char* argv[]) { replace_payload = true; } - // Read RTP file header. - if (NETEQTEST_RTPpacket::skipFileHeader(in_file) != 0) { - std::cerr << "Wrong format in RTP file" << std::endl; - exit(1); - } - // Enable tracing. webrtc::Trace::CreateTrace(); webrtc::Trace::SetTraceFile((webrtc::test::OutputPath() + @@ -182,25 +172,17 @@ int main(int argc, char* argv[]) { RegisterPayloadTypes(neteq); // Read first packet. - NETEQTEST_RTPpacket* rtp; - NETEQTEST_RTPpacket* next_rtp = NULL; - if (!FLAGS_dummy_rtp) { - rtp = new NETEQTEST_RTPpacket(); - if (replace_payload) { - next_rtp = new NETEQTEST_RTPpacket(); - } - } else { - rtp = new NETEQTEST_DummyRTPpacket(); - if (replace_payload) { - next_rtp = new NETEQTEST_DummyRTPpacket(); - } - } - rtp->readFromFile(in_file); - if (rtp->dataLen() < 0) { - std::cout << "Warning: RTP file is empty" << std::endl; + if (file_source->EndOfFile()) { + printf("Warning: RTP file is empty"); + webrtc::Trace::ReturnTrace(); + return 0; } + webrtc::scoped_ptr packet(file_source->NextPacket()); + bool packet_available = true; // Set up variables for audio replacement if needed. + webrtc::scoped_ptr next_packet; + bool next_packet_available = false; size_t input_frame_size_timestamps = 0; webrtc::scoped_ptr replacement_audio; webrtc::scoped_ptr payload; @@ -213,13 +195,15 @@ int main(int argc, char* argv[]) { replacement_audio.reset(new int16_t[input_frame_size_timestamps]); payload_mem_size_bytes = 2 * input_frame_size_timestamps; payload.reset(new uint8_t[payload_mem_size_bytes]); - assert(next_rtp); - next_rtp->readFromFile(in_file); + assert(!file_source->EndOfFile()); + next_packet.reset(file_source->NextPacket()); + next_packet_available = true; } // This is the main simulation loop. - int time_now_ms = rtp->time(); // Start immediately with the first packet. - int next_input_time_ms = rtp->time(); + // Set the simulation clock to start immediately with the first packet. + int time_now_ms = packet->time_ms(); + int next_input_time_ms = time_now_ms; int next_output_time_ms = time_now_ms; if (time_now_ms % kOutputBlockSizeMs != 0) { // Make sure that next_output_time_ms is rounded up to the next multiple @@ -227,43 +211,52 @@ int main(int argc, char* argv[]) { next_output_time_ms += kOutputBlockSizeMs - time_now_ms % kOutputBlockSizeMs; } - while (rtp->dataLen() >= 0) { + while (packet_available) { // Check if it is time to insert packet. - while (time_now_ms >= next_input_time_ms && rtp->dataLen() >= 0) { - if (rtp->dataLen() > 0) { - // Parse RTP header. - WebRtcRTPHeader rtp_header; - rtp->parseHeader(&rtp_header); - uint8_t* payload_ptr = rtp->payload(); - size_t payload_len = rtp->payloadLen(); - if (replace_payload) { - payload_len = ReplacePayload(replacement_audio_file.get(), - &replacement_audio, - &payload, - &payload_mem_size_bytes, - &input_frame_size_timestamps, - &rtp_header, - next_rtp); - payload_ptr = payload.get(); - } - int error = neteq->InsertPacket(rtp_header, payload_ptr, - static_cast(payload_len), - rtp->time() * sample_rate_hz / 1000); - if (error != NetEq::kOK) { - std::cerr << "InsertPacket returned error code " << - neteq->LastError() << std::endl; - } - } - // Get next packet from file. - rtp->readFromFile(in_file); + while (time_now_ms >= next_input_time_ms && packet_available) { + assert(packet->virtual_payload_length_bytes() > 0); + // Parse RTP header. + WebRtcRTPHeader rtp_header; + packet->ConvertHeader(&rtp_header); + const uint8_t* payload_ptr = packet->payload(); + size_t payload_len = packet->payload_length_bytes(); if (replace_payload) { - // At this point |rtp| contains the packet *after* |next_rtp|. - // Swap RTP packet objects between |rtp| and |next_rtp|. - NETEQTEST_RTPpacket* temp_rtp = rtp; - rtp = next_rtp; - next_rtp = temp_rtp; + payload_len = ReplacePayload(replacement_audio_file.get(), + &replacement_audio, + &payload, + &payload_mem_size_bytes, + &input_frame_size_timestamps, + &rtp_header, + next_packet.get()); + payload_ptr = payload.get(); } - next_input_time_ms = rtp->time(); + int error = + neteq->InsertPacket(rtp_header, + payload_ptr, + static_cast(payload_len), + packet->time_ms() * sample_rate_hz / 1000); + if (error != NetEq::kOK) { + std::cerr << "InsertPacket returned error code " << neteq->LastError() + << std::endl; + } + + // Get next packet from file. + if (!file_source->EndOfFile()) { + packet.reset(file_source->NextPacket()); + } else { + packet_available = false; + } + if (replace_payload) { + // At this point |packet| contains the packet *after* |next_packet|. + // Swap Packet objects between |packet| and |next_packet|. + packet.swap(next_packet); + // Swap the status indicators unless they're already the same. + if (packet_available != next_packet_available) { + packet_available = !packet_available; + next_packet_available = !next_packet_available; + } + } + next_input_time_ms = packet->time_ms(); } // Check if it is time to get output audio. @@ -300,10 +293,7 @@ int main(int argc, char* argv[]) { std::cout << "Simulation done" << std::endl; - fclose(in_file); fclose(out_file); - delete rtp; - delete next_rtp; delete neteq; webrtc::Trace::ReturnTrace(); return 0; @@ -503,7 +493,7 @@ size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, size_t* payload_mem_size_bytes, size_t* frame_size_samples, WebRtcRTPHeader* rtp_header, - NETEQTEST_RTPpacket* next_rtp) { + const webrtc::test::Packet* next_packet) { size_t payload_len = 0; // Check for CNG. if (IsComfortNosie(rtp_header->header.payloadType)) { @@ -515,18 +505,18 @@ size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, (*payload)[0] = 127; // Max attenuation of CNG. payload_len = 1; } else { - if (next_rtp->payloadLen() > 0) { - // Check if payload length has changed. - if (next_rtp->sequenceNumber() == rtp_header->header.sequenceNumber + 1) { - if (*frame_size_samples != - next_rtp->timeStamp() - rtp_header->header.timestamp) { - *frame_size_samples = - next_rtp->timeStamp() - rtp_header->header.timestamp; - (*replacement_audio).reset( - new int16_t[*frame_size_samples]); - *payload_mem_size_bytes = 2 * *frame_size_samples; - (*payload).reset(new uint8_t[*payload_mem_size_bytes]); - } + assert(next_packet->virtual_payload_length_bytes() > 0); + // Check if payload length has changed. + if (next_packet->header().sequenceNumber == + rtp_header->header.sequenceNumber + 1) { + if (*frame_size_samples != + next_packet->header().timestamp - rtp_header->header.timestamp) { + *frame_size_samples = + next_packet->header().timestamp - rtp_header->header.timestamp; + (*replacement_audio).reset( + new int16_t[*frame_size_samples]); + *payload_mem_size_bytes = 2 * *frame_size_samples; + (*payload).reset(new uint8_t[*payload_mem_size_bytes]); } } // Get new speech. @@ -545,7 +535,7 @@ size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, assert(*frame_size_samples > 0); if (!replacement_audio_file->Read(*frame_size_samples, (*replacement_audio).get())) { - std::cerr << "Could no read replacement audio file." << std::endl; + std::cerr << "Could not read replacement audio file." << std::endl; webrtc::Trace::ReturnTrace(); exit(1); } diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.cc b/webrtc/modules/audio_coding/neteq/tools/packet.cc index d8fb7134f1..794c308e61 100644 --- a/webrtc/modules/audio_coding/neteq/tools/packet.cc +++ b/webrtc/modules/audio_coding/neteq/tools/packet.cc @@ -9,6 +9,10 @@ */ #include "webrtc/modules/audio_coding/neteq/tools/packet.h" + +#include + +#include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" namespace webrtc { @@ -117,6 +121,14 @@ void Packet::DeleteRedHeaders(std::list* headers) { } } +void Packet::ConvertHeader(WebRtcRTPHeader* copy_to) const { + memcpy(©_to->header, &header_, sizeof(header_)); + copy_to->frameType = kAudioFrameSpeech; + copy_to->type.Audio.numEnergy = 0; + copy_to->type.Audio.channel = 1; + copy_to->type.Audio.isCNG = false; +} + bool Packet::ParseHeader(const RtpHeaderParser& parser) { bool valid_header = parser.Parse( payload_memory_.get(), static_cast(packet_length_bytes_), &header_); diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.h b/webrtc/modules/audio_coding/neteq/tools/packet.h index eb8ce28a22..df7aeb7495 100644 --- a/webrtc/modules/audio_coding/neteq/tools/packet.h +++ b/webrtc/modules/audio_coding/neteq/tools/packet.h @@ -21,6 +21,7 @@ namespace webrtc { class RtpHeaderParser; +struct WebRtcRTPHeader; namespace test { @@ -89,6 +90,10 @@ class Packet { const RTPHeader& header() const { return header_; } + // Copies the packet header information, converting from the native RTPHeader + // type to WebRtcRTPHeader. + void ConvertHeader(WebRtcRTPHeader* copy_to) const; + void set_time_ms(double time) { time_ms_ = time; } double time_ms() const { return time_ms_; } bool valid_header() const { return valid_header_; } diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc index 773cc2c896..b07de0b81d 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc @@ -59,11 +59,6 @@ int main(int argc, char* argv[]) { return 0; } - FILE* in_file = fopen(argv[1], "rb"); - if (!in_file) { - printf("Cannot open input file %s\n", argv[1]); - return -1; - } printf("Input file: %s\n", argv[1]); webrtc::scoped_ptr file_source( webrtc::test::RtpFileSource::Create(argv[1])); @@ -140,7 +135,6 @@ int main(int argc, char* argv[]) { } } - fclose(in_file); fclose(out_file); return 0;