Make rtc_event_log2text output header extensions

BUG=webrtc:none

Review-Url: https://codereview.webrtc.org/2918103002
Cr-Commit-Position: refs/heads/master@{#18530}
This commit is contained in:
ilnik
2017-06-12 01:02:46 -07:00
committed by Commit Bot
parent 3fae628094
commit a8e781aedf
4 changed files with 95 additions and 47 deletions

View File

@ -9,8 +9,10 @@
*/
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <utility> // pair
#include "gflags/gflags.h"
#include "webrtc/base/checks.h"
@ -439,14 +441,13 @@ int main(int argc, char* argv[]) {
size_t total_length;
uint8_t header[IP_PACKET_SIZE];
webrtc::PacketDirection direction;
parsed_stream.GetRtpHeader(i, &direction, header, &header_length,
&total_length);
webrtc::RtpHeaderExtensionMap* extension_map = parsed_stream.GetRtpHeader(
i, &direction, header, &header_length, &total_length);
// Parse header to get SSRC and RTP time.
webrtc::RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
webrtc::RTPHeader parsed_header;
rtp_parser.Parse(&parsed_header);
rtp_parser.Parse(&parsed_header, extension_map);
MediaType media_type =
parsed_stream.GetMediaType(parsed_header.ssrc, direction);
@ -456,7 +457,31 @@ int main(int argc, char* argv[]) {
std::cout << parsed_stream.GetTimestamp(i) << "\tRTP"
<< StreamInfo(direction, media_type)
<< "\tssrc=" << parsed_header.ssrc
<< "\ttimestamp=" << parsed_header.timestamp << std::endl;
<< "\ttimestamp=" << parsed_header.timestamp;
if (parsed_header.extension.hasAbsoluteSendTime) {
std::cout << "\tAbsSendTime="
<< parsed_header.extension.absoluteSendTime;
}
if (parsed_header.extension.hasVideoContentType) {
std::cout << "\tContentType="
<< static_cast<int>(parsed_header.extension.videoContentType);
}
if (parsed_header.extension.hasVideoRotation) {
std::cout << "\tRotation="
<< static_cast<int>(parsed_header.extension.videoRotation);
}
if (parsed_header.extension.hasTransportSequenceNumber) {
std::cout << "\tTransportSeq="
<< parsed_header.extension.transportSequenceNumber;
}
if (parsed_header.extension.hasTransmissionTimeOffset) {
std::cout << "\tTransmTimeOffset="
<< parsed_header.extension.transmissionTimeOffset;
}
if (parsed_header.extension.hasAudioLevel) {
std::cout << "\tAudioLevel=" << parsed_header.extension.audioLevel;
}
std::cout << std::endl;
}
if (!FLAGS_nortcp &&
parsed_stream.GetEventType(i) ==

View File

@ -158,6 +158,12 @@ bool ParsedRtcEventLog::ParseStream(std::istream& stream) {
// Check whether we have reached end of file.
stream.peek();
if (stream.eof()) {
// Process all extensions maps for faster look-up later.
for (auto& event_stream : streams_) {
rtp_extensions_maps_[StreamId(event_stream.ssrc,
event_stream.direction)] =
&event_stream.rtp_extensions_map;
}
return true;
}
@ -204,34 +210,41 @@ bool ParsedRtcEventLog::ParseStream(std::istream& stream) {
case VIDEO_RECEIVER_CONFIG_EVENT: {
rtclog::StreamConfig config = GetVideoReceiveConfig(event);
streams_.emplace_back(config.remote_ssrc, MediaType::VIDEO,
kIncomingPacket);
kIncomingPacket,
RtpHeaderExtensionMap(config.rtp_extensions));
streams_.emplace_back(config.local_ssrc, MediaType::VIDEO,
kOutgoingPacket);
kOutgoingPacket,
RtpHeaderExtensionMap(config.rtp_extensions));
break;
}
case VIDEO_SENDER_CONFIG_EVENT: {
std::vector<rtclog::StreamConfig> configs = GetVideoSendConfig(event);
for (size_t i = 0; i < configs.size(); i++) {
streams_.emplace_back(configs[i].local_ssrc, MediaType::VIDEO,
kOutgoingPacket);
streams_.emplace_back(
configs[i].local_ssrc, MediaType::VIDEO, kOutgoingPacket,
RtpHeaderExtensionMap(configs[i].rtp_extensions));
streams_.emplace_back(configs[i].rtx_ssrc, MediaType::VIDEO,
kOutgoingPacket);
streams_.emplace_back(
configs[i].rtx_ssrc, MediaType::VIDEO, kOutgoingPacket,
RtpHeaderExtensionMap(configs[i].rtp_extensions));
}
break;
}
case AUDIO_RECEIVER_CONFIG_EVENT: {
rtclog::StreamConfig config = GetAudioReceiveConfig(event);
streams_.emplace_back(config.remote_ssrc, MediaType::AUDIO,
kIncomingPacket);
kIncomingPacket,
RtpHeaderExtensionMap(config.rtp_extensions));
streams_.emplace_back(config.local_ssrc, MediaType::AUDIO,
kOutgoingPacket);
kOutgoingPacket,
RtpHeaderExtensionMap(config.rtp_extensions));
break;
}
case AUDIO_SENDER_CONFIG_EVENT: {
rtclog::StreamConfig config = GetAudioSendConfig(event);
streams_.emplace_back(config.local_ssrc, MediaType::AUDIO,
kOutgoingPacket);
kOutgoingPacket,
RtpHeaderExtensionMap(config.rtp_extensions));
break;
}
default:
@ -262,7 +275,8 @@ ParsedRtcEventLog::EventType ParsedRtcEventLog::GetEventType(
}
// The header must have space for at least IP_PACKET_SIZE bytes.
void ParsedRtcEventLog::GetRtpHeader(size_t index,
webrtc::RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeader(
size_t index,
PacketDirection* incoming,
uint8_t* header,
size_t* header_length,
@ -295,7 +309,15 @@ void ParsedRtcEventLog::GetRtpHeader(size_t index,
RTC_CHECK_LE(rtp_packet.header().size(),
static_cast<size_t>(IP_PACKET_SIZE));
memcpy(header, rtp_packet.header().data(), rtp_packet.header().size());
uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(header + 8);
StreamId stream_id(
ssrc, rtp_packet.incoming() ? kIncomingPacket : kOutgoingPacket);
auto it = rtp_extensions_maps_.find(stream_id);
if (it != rtp_extensions_maps_.end()) {
return it->second;
}
}
return nullptr;
}
// The packet must have space for at least IP_PACKET_SIZE bytes.

View File

@ -10,11 +10,15 @@
#ifndef WEBRTC_LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
#define WEBRTC_LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
#include <map>
#include <string>
#include <utility> // pair
#include <vector>
#include "webrtc/base/ignore_wundef.h"
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/video_receive_stream.h"
#include "webrtc/video_send_stream.h"
@ -99,7 +103,11 @@ class ParsedRtcEventLog {
// parameters. Each output parameter can be set to nullptr if that value
// isn't needed.
// NB: The header must have space for at least IP_PACKET_SIZE bytes.
void GetRtpHeader(size_t index,
// Returns: a pointer to a header extensions map acquired from parsing
// corresponding Audio/Video Sender/Receiver config events.
// Warning: if the same SSRC is reused by both video and audio streams during
// call, extensions maps may be incorrect (the last one would be returned).
webrtc::RtpHeaderExtensionMap* GetRtpHeader(size_t index,
PacketDirection* incoming,
uint8_t* header,
size_t* header_length,
@ -178,15 +186,25 @@ class ParsedRtcEventLog {
struct Stream {
Stream(uint32_t ssrc,
MediaType media_type,
webrtc::PacketDirection direction)
: ssrc(ssrc), media_type(media_type), direction(direction) {}
webrtc::PacketDirection direction,
webrtc::RtpHeaderExtensionMap map)
: ssrc(ssrc),
media_type(media_type),
direction(direction),
rtp_extensions_map(map) {}
uint32_t ssrc;
MediaType media_type;
webrtc::PacketDirection direction;
webrtc::RtpHeaderExtensionMap rtp_extensions_map;
};
// All configured streams found in the event log.
std::vector<Stream> streams_;
// To find configured extensions map for given stream, what are needed to
// parse a header.
typedef std::pair<uint32_t, webrtc::PacketDirection> StreamId;
std::map<StreamId, webrtc::RtpHeaderExtensionMap*> rtp_extensions_maps_;
};
} // namespace webrtc

View File

@ -289,10 +289,6 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
uint64_t first_timestamp = std::numeric_limits<uint64_t>::max();
uint64_t last_timestamp = std::numeric_limits<uint64_t>::min();
// Maps a stream identifier consisting of ssrc and direction
// to the header extensions used by that stream,
std::map<StreamId, RtpHeaderExtensionMap> extension_maps;
PacketDirection direction;
uint8_t header[IP_PACKET_SIZE];
size_t header_length;
@ -323,11 +319,8 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
case ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT: {
rtclog::StreamConfig config = parsed_log_.GetVideoReceiveConfig(i);
StreamId stream(config.remote_ssrc, kIncomingPacket);
extension_maps[stream] = RtpHeaderExtensionMap(config.rtp_extensions);
video_ssrcs_.insert(stream);
StreamId rtx_stream(config.rtx_ssrc, kIncomingPacket);
extension_maps[rtx_stream] =
RtpHeaderExtensionMap(config.rtp_extensions);
video_ssrcs_.insert(rtx_stream);
rtx_ssrcs_.insert(rtx_stream);
break;
@ -337,12 +330,8 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
parsed_log_.GetVideoSendConfig(i);
for (const auto& config : configs) {
StreamId stream(config.local_ssrc, kOutgoingPacket);
extension_maps[stream] =
RtpHeaderExtensionMap(config.rtp_extensions);
video_ssrcs_.insert(stream);
StreamId rtx_stream(config.rtx_ssrc, kOutgoingPacket);
extension_maps[rtx_stream] =
RtpHeaderExtensionMap(config.rtp_extensions);
video_ssrcs_.insert(rtx_stream);
rtx_ssrcs_.insert(rtx_stream);
}
@ -351,28 +340,21 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
case ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT: {
rtclog::StreamConfig config = parsed_log_.GetAudioReceiveConfig(i);
StreamId stream(config.remote_ssrc, kIncomingPacket);
extension_maps[stream] = RtpHeaderExtensionMap(config.rtp_extensions);
audio_ssrcs_.insert(stream);
break;
}
case ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT: {
rtclog::StreamConfig config = parsed_log_.GetAudioSendConfig(i);
StreamId stream(config.local_ssrc, kOutgoingPacket);
extension_maps[stream] = RtpHeaderExtensionMap(config.rtp_extensions);
audio_ssrcs_.insert(stream);
break;
}
case ParsedRtcEventLog::RTP_EVENT: {
parsed_log_.GetRtpHeader(i, &direction, header, &header_length,
&total_length);
// Parse header to get SSRC.
RtpHeaderExtensionMap* extension_map = parsed_log_.GetRtpHeader(
i, &direction, header, &header_length, &total_length);
RtpUtility::RtpHeaderParser rtp_parser(header, header_length);
RTPHeader parsed_header;
rtp_parser.Parse(&parsed_header);
StreamId stream(parsed_header.ssrc, direction);
// Look up the extension_map and parse it again to get the extensions.
if (extension_maps.count(stream) == 1) {
RtpHeaderExtensionMap* extension_map = &extension_maps[stream];
if (extension_map != nullptr) {
rtp_parser.Parse(&parsed_header, extension_map);
} else {
// Use the default extension map.
@ -382,6 +364,7 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
rtp_parser.Parse(&parsed_header, &default_extension_map);
}
uint64_t timestamp = parsed_log_.GetTimestamp(i);
StreamId stream(parsed_header.ssrc, direction);
rtp_packets_[stream].push_back(
LoggedRtpPacket(timestamp, parsed_header, total_length));
break;