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:
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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)) {
|
||||||
|
Reference in New Issue
Block a user