diff --git a/webrtc/modules/audio_coding/neteq/neteq.gypi b/webrtc/modules/audio_coding/neteq/neteq.gypi index 01143bc5ee..34d64a1fb0 100644 --- a/webrtc/modules/audio_coding/neteq/neteq.gypi +++ b/webrtc/modules/audio_coding/neteq/neteq.gypi @@ -170,6 +170,7 @@ 'type': 'static_library', 'dependencies': [ 'rtp_rtcp', + '<(webrtc_root)/test/webrtc_test_common.gyp:webrtc_test_common', ], 'direct_dependent_settings': { 'include_dirs': [ diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc index e144ba72a0..3d5bd60341 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc @@ -172,12 +172,12 @@ int main(int argc, char* argv[]) { RegisterPayloadTypes(neteq); // Read first packet. - if (file_source->EndOfFile()) { + webrtc::scoped_ptr packet(file_source->NextPacket()); + if (!packet) { 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. @@ -195,8 +195,8 @@ 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(!file_source->EndOfFile()); next_packet.reset(file_source->NextPacket()); + assert(next_packet); next_packet_available = true; } @@ -241,8 +241,9 @@ int main(int argc, char* argv[]) { } // Get next packet from file. - if (!file_source->EndOfFile()) { - packet.reset(file_source->NextPacket()); + webrtc::test::Packet* temp_packet = file_source->NextPacket(); + if (temp_packet) { + packet.reset(temp_packet); } else { packet_available = false; } diff --git a/webrtc/modules/audio_coding/neteq/tools/packet_source.h b/webrtc/modules/audio_coding/neteq/tools/packet_source.h index ab9ef83eea..0b724b1f46 100644 --- a/webrtc/modules/audio_coding/neteq/tools/packet_source.h +++ b/webrtc/modules/audio_coding/neteq/tools/packet_source.h @@ -24,7 +24,7 @@ class Packet; // Interface class for an object delivering RTP packets to test applications. class PacketSource { public: - PacketSource() {} + PacketSource() : use_ssrc_filter_(false), ssrc_(0) {} virtual ~PacketSource() {} // Returns a pointer to the next packet. Returns NULL if the source is @@ -35,8 +35,16 @@ class PacketSource { filter_.set(payload_type, true); } + virtual void SelectSsrc(uint32_t ssrc) { + use_ssrc_filter_ = true; + ssrc_ = ssrc; + } + protected: std::bitset<128> filter_; // Payload type is 7 bits in the RFC. + // If SSRC filtering discards all packet that do not match the SSRC. + bool use_ssrc_filter_; // True when SSRC filtering is active. + uint32_t ssrc_; // The selected SSRC. All other SSRCs will be discarded. private: DISALLOW_COPY_AND_ASSIGN(PacketSource); diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc index b07de0b81d..ec604d2066 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc @@ -91,13 +91,12 @@ int main(int argc, char* argv[]) { fprintf(out_file, "\n"); webrtc::scoped_ptr packet; - while (!file_source->EndOfFile()) { + while (true) { packet.reset(file_source->NextPacket()); if (!packet.get()) { - // This is probably an RTCP packet. Move on to the next one. - continue; + // End of file reached. + break; } - assert(packet.get()); // Write packet data to file. fprintf(out_file, "%5u %10u %10u %5i %5i %2i %#08X", diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc index 6924a7f244..6667afc5bd 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc @@ -18,26 +18,21 @@ #include #endif +#include "webrtc/base/checks.h" #include "webrtc/modules/audio_coding/neteq/tools/packet.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/test/rtp_file_reader.h" namespace webrtc { namespace test { RtpFileSource* RtpFileSource::Create(const std::string& file_name) { - RtpFileSource* source = new RtpFileSource; - assert(source); - if (!source->OpenFile(file_name) || !source->SkipFileHeader()) { - assert(false); - delete source; - return NULL; - } + RtpFileSource* source = new RtpFileSource(); + CHECK(source->OpenFile(file_name)); return source; } RtpFileSource::~RtpFileSource() { - if (in_file_) - fclose(in_file_); } bool RtpFileSource::RegisterRtpHeaderExtension(RTPExtensionType type, @@ -47,102 +42,48 @@ bool RtpFileSource::RegisterRtpHeaderExtension(RTPExtensionType type, } Packet* RtpFileSource::NextPacket() { - while (!EndOfFile()) { - uint16_t length; - if (fread(&length, sizeof(length), 1, in_file_) == 0) { - assert(false); + while (true) { + RtpFileReader::Packet temp_packet; + if (!rtp_reader_->NextPacket(&temp_packet)) { return NULL; } - length = ntohs(length); - - uint16_t plen; - if (fread(&plen, sizeof(plen), 1, in_file_) == 0) { - assert(false); - return NULL; - } - plen = ntohs(plen); - - uint32_t offset; - if (fread(&offset, sizeof(offset), 1, in_file_) == 0) { - assert(false); - return NULL; - } - offset = ntohl(offset); - - // Use length here because a plen of 0 specifies RTCP. - assert(length >= kPacketHeaderSize); - size_t packet_size_bytes = length - kPacketHeaderSize; - if (packet_size_bytes == 0) { + if (temp_packet.length == 0) { // May be an RTCP packet. // Read the next one. continue; } - scoped_ptr packet_memory(new uint8_t[packet_size_bytes]); - if (fread(packet_memory.get(), 1, packet_size_bytes, in_file_) != - packet_size_bytes) { - assert(false); - return NULL; - } + scoped_ptr packet_memory(new uint8_t[temp_packet.length]); + memcpy(packet_memory.get(), temp_packet.data, temp_packet.length); scoped_ptr packet(new Packet(packet_memory.release(), - packet_size_bytes, - plen, - offset, + temp_packet.length, + temp_packet.original_length, + temp_packet.time_ms, *parser_.get())); if (!packet->valid_header()) { assert(false); return NULL; } - if (filter_.test(packet->header().payloadType)) { + if (filter_.test(packet->header().payloadType) || + (use_ssrc_filter_ && packet->header().ssrc != ssrc_)) { // This payload type should be filtered out. Continue to the next packet. continue; } return packet.release(); } - return NULL; -} - -bool RtpFileSource::EndOfFile() const { - assert(in_file_); - return ftell(in_file_) >= file_end_; } RtpFileSource::RtpFileSource() : PacketSource(), - in_file_(NULL), - file_end_(-1), parser_(RtpHeaderParser::Create()) {} bool RtpFileSource::OpenFile(const std::string& file_name) { - in_file_ = fopen(file_name.c_str(), "rb"); - assert(in_file_); - if (in_file_ == NULL) { - return false; - } - - // Find out how long the file is. - fseek(in_file_, 0, SEEK_END); - file_end_ = ftell(in_file_); - rewind(in_file_); - return true; -} - -bool RtpFileSource::SkipFileHeader() { - char firstline[kFirstLineLength]; - assert(in_file_); - if (fgets(firstline, kFirstLineLength, in_file_) == NULL) { - assert(false); - return false; - } - // Check that the first line is ok. - if ((strncmp(firstline, "#!rtpplay1.0", 12) != 0) && - (strncmp(firstline, "#!RTPencode1.0", 14) != 0)) { - assert(false); - return false; - } - // Skip the file header. - if (fseek(in_file_, kRtpFileHeaderSize, SEEK_CUR) != 0) { - assert(false); - return false; + rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kRtpDump, file_name)); + if (rtp_reader_) + return true; + rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kPcap, file_name)); + if (!rtp_reader_) { + FATAL() << "Couldn't open input file as either a rtpdump or .pcap. Note " + "that .pcapng is not supported."; } return true; } diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h index 6b92a88698..d30928066f 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h @@ -26,6 +26,8 @@ class RtpHeaderParser; namespace test { +class RtpFileReader; + class RtpFileSource : public PacketSource { public: // Creates an RtpFileSource reading from |file_name|. If the file cannot be @@ -39,10 +41,7 @@ class RtpFileSource : public PacketSource { // Returns a pointer to the next packet. Returns NULL if end of file was // reached, or if a the data was corrupt. - virtual Packet* NextPacket(); - - // Returns true if the end of file has been reached. - virtual bool EndOfFile() const; + virtual Packet* NextPacket() OVERRIDE; private: static const int kFirstLineLength = 40; @@ -53,10 +52,7 @@ class RtpFileSource : public PacketSource { bool OpenFile(const std::string& file_name); - bool SkipFileHeader(); - - FILE* in_file_; - int64_t file_end_; + scoped_ptr rtp_reader_; scoped_ptr parser_; DISALLOW_COPY_AND_ASSIGN(RtpFileSource);