Do basic parsing of RTCP headers in PcapFileReader to enable log filtering.

BUG=
R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1697004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4266 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
solenberg@webrtc.org
2013-06-26 08:36:07 +00:00
parent 892d750ba6
commit a5fd2f1348
3 changed files with 44 additions and 10 deletions

View File

@ -49,8 +49,12 @@ namespace webrtc {
namespace ModuleRTPUtility { namespace ModuleRTPUtility {
enum { enum {
kRtcpExpectedVersion = 2,
kRtcpMinHeaderLength = 4, kRtcpMinHeaderLength = 4,
kRtcpExpectedVersion = 2 kRtcpMinParseLength = 8,
kRtpExpectedVersion = 2,
kRtpMinParseLength = 12
}; };
/* /*
@ -291,11 +295,39 @@ bool RTPHeaderParser::RTCP() const {
return RTCP; 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, bool RTPHeaderParser::Parse(RTPHeader& header,
RtpHeaderExtensionMap* ptrExtensionMap) const { RtpHeaderExtensionMap* ptrExtensionMap) const {
const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin; const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
if (length < kRtpMinParseLength) {
if (length < 12) {
return false; return false;
} }
@ -325,7 +357,7 @@ bool RTPHeaderParser::Parse(RTPHeader& header,
SSRC += *ptr++ << 8; SSRC += *ptr++ << 8;
SSRC += *ptr++; SSRC += *ptr++;
if (V != 2) { if (V != kRtpExpectedVersion) {
return false; return false;
} }

View File

@ -124,6 +124,7 @@ namespace ModuleRTPUtility
~RTPHeaderParser(); ~RTPHeaderParser();
bool RTCP() const; bool RTCP() const;
bool ParseRtcp(RTPHeader* header) const;
bool Parse(RTPHeader& parsedPacket, bool Parse(RTPHeader& parsedPacket,
RtpHeaderExtensionMap* ptrExtensionMap = NULL) const; RtpHeaderExtensionMap* ptrExtensionMap = NULL) const;

View File

@ -114,10 +114,9 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
uint32_t stream_start_ms = 0; uint32_t stream_start_ms = 0;
int32_t next_packet_pos = ftell(file_); int32_t next_packet_pos = ftell(file_);
for (;;) { for (;;) {
++total_packet_count;
TRY(fseek(file_, next_packet_pos, SEEK_SET)); TRY(fseek(file_, next_packet_pos, SEEK_SET));
int result = ReadPacket(&next_packet_pos, stream_start_ms, int result = ReadPacket(&next_packet_pos, stream_start_ms,
total_packet_count); ++total_packet_count);
if (result == kResultFail) { if (result == kResultFail) {
break; break;
} else if (result == kResultSuccess && packets_.size() == 1) { } else if (result == kResultSuccess && packets_.size() == 1) {
@ -140,8 +139,9 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
mit != packets_by_ssrc_.end(); ++mit) { mit != packets_by_ssrc_.end(); ++mit) {
uint32_t ssrc = mit->first; uint32_t ssrc = mit->first;
const std::vector<uint32_t>& packet_numbers = mit->second; const std::vector<uint32_t>& packet_numbers = mit->second;
printf("SSRC: %08x, %d packets\n", ssrc, uint8_t pt = packets_[packet_numbers[0]].rtp_header.payloadType;
static_cast<int>(packet_numbers.size())); printf("SSRC: %08x, %d packets, pt=%d\n", ssrc,
static_cast<int>(packet_numbers.size()), pt);
} }
// TODO(solenberg): Better validation of identified SSRC streams. // TODO(solenberg): Better validation of identified SSRC streams.
@ -187,14 +187,14 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
private: private:
// A marker of an RTP packet within the file. // A marker of an RTP packet within the file.
struct RtpPacketMarker { struct RtpPacketMarker {
uint32_t packet_number; uint32_t packet_number; // One-based index (like in WireShark)
uint32_t time_offset_ms; uint32_t time_offset_ms;
uint32_t source_ip; uint32_t source_ip;
uint32_t dest_ip; uint32_t dest_ip;
uint16_t source_port; uint16_t source_port;
uint16_t dest_port; uint16_t dest_port;
RTPHeader rtp_header; 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; uint32_t payload_length;
}; };
@ -270,6 +270,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
ModuleRTPUtility::RTPHeaderParser rtp_parser(read_buffer_, ModuleRTPUtility::RTPHeaderParser rtp_parser(read_buffer_,
marker.payload_length); marker.payload_length);
if (rtp_parser.RTCP()) { if (rtp_parser.RTCP()) {
rtp_parser.ParseRtcp(&marker.rtp_header);
packets_.push_back(marker); packets_.push_back(marker);
} else { } else {
if (!rtp_parser.Parse(marker.rtp_header, NULL)) { if (!rtp_parser.Parse(marker.rtp_header, NULL)) {