diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc index c0751c6f3b..4a3a1432fc 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc @@ -49,8 +49,12 @@ namespace webrtc { namespace ModuleRTPUtility { enum { + kRtcpExpectedVersion = 2, kRtcpMinHeaderLength = 4, - kRtcpExpectedVersion = 2 + kRtcpMinParseLength = 8, + + kRtpExpectedVersion = 2, + kRtpMinParseLength = 12 }; /* @@ -291,11 +295,39 @@ bool RTPHeaderParser::RTCP() const { return RTCP; } +bool RTPHeaderParser::ParseRtcp(RTPHeader* header) const { + assert(header != NULL); + + const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin; + if (length < kRtcpMinParseLength) { + return false; + } + + const uint8_t V = _ptrRTPDataBegin[0] >> 6; + if (V != kRtcpExpectedVersion) { + return false; + } + + const uint8_t PT = _ptrRTPDataBegin[1]; + const uint16_t len = (_ptrRTPDataBegin[2] << 8) + _ptrRTPDataBegin[3]; + const uint8_t* ptr = &_ptrRTPDataBegin[4]; + + uint32_t SSRC = *ptr++ << 24; + SSRC += *ptr++ << 16; + SSRC += *ptr++ << 8; + SSRC += *ptr++; + + header->payloadType = PT; + header->ssrc = SSRC; + header->headerLength = 4 + (len << 2); + + return true; +} + bool RTPHeaderParser::Parse(RTPHeader& header, RtpHeaderExtensionMap* ptrExtensionMap) const { const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin; - - if (length < 12) { + if (length < kRtpMinParseLength) { return false; } @@ -325,7 +357,7 @@ bool RTPHeaderParser::Parse(RTPHeader& header, SSRC += *ptr++ << 8; SSRC += *ptr++; - if (V != 2) { + if (V != kRtpExpectedVersion) { return false; } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.h b/webrtc/modules/rtp_rtcp/source/rtp_utility.h index 28670f98c9..3bae7324aa 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_utility.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.h @@ -124,6 +124,7 @@ namespace ModuleRTPUtility ~RTPHeaderParser(); bool RTCP() const; + bool ParseRtcp(RTPHeader* header) const; bool Parse(RTPHeader& parsedPacket, RtpHeaderExtensionMap* ptrExtensionMap = NULL) const; diff --git a/webrtc/modules/video_coding/main/test/pcap_file_reader.cc b/webrtc/modules/video_coding/main/test/pcap_file_reader.cc index 628c41c48f..326fab85c3 100644 --- a/webrtc/modules/video_coding/main/test/pcap_file_reader.cc +++ b/webrtc/modules/video_coding/main/test/pcap_file_reader.cc @@ -114,10 +114,9 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface { uint32_t stream_start_ms = 0; int32_t next_packet_pos = ftell(file_); for (;;) { - ++total_packet_count; TRY(fseek(file_, next_packet_pos, SEEK_SET)); int result = ReadPacket(&next_packet_pos, stream_start_ms, - total_packet_count); + ++total_packet_count); if (result == kResultFail) { break; } else if (result == kResultSuccess && packets_.size() == 1) { @@ -140,8 +139,9 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface { mit != packets_by_ssrc_.end(); ++mit) { uint32_t ssrc = mit->first; const std::vector& packet_numbers = mit->second; - printf("SSRC: %08x, %d packets\n", ssrc, - static_cast(packet_numbers.size())); + uint8_t pt = packets_[packet_numbers[0]].rtp_header.payloadType; + printf("SSRC: %08x, %d packets, pt=%d\n", ssrc, + static_cast(packet_numbers.size()), pt); } // TODO(solenberg): Better validation of identified SSRC streams. @@ -187,14 +187,14 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface { private: // A marker of an RTP packet within the file. struct RtpPacketMarker { - uint32_t packet_number; + uint32_t packet_number; // One-based index (like in WireShark) uint32_t time_offset_ms; uint32_t source_ip; uint32_t dest_ip; uint16_t source_port; uint16_t dest_port; RTPHeader rtp_header; - int32_t pos_in_file; + int32_t pos_in_file; // Byte offset of payload from start of file. uint32_t payload_length; }; @@ -270,6 +270,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface { ModuleRTPUtility::RTPHeaderParser rtp_parser(read_buffer_, marker.payload_length); if (rtp_parser.RTCP()) { + rtp_parser.ParseRtcp(&marker.rtp_header); packets_.push_back(marker); } else { if (!rtp_parser.Parse(marker.rtp_header, NULL)) {