RtcEventLogSource no longer uses deprecated parsing functions.

Also remove header extension map from NetEqEventLogInput and RtcEventLogSource.

Bug: webrtc:8111
Change-Id: Ic9be7b03e32ab8aa12284596e21e53b6763f483a
Reviewed-on: https://webrtc-review.googlesource.com/c/102622
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25122}
This commit is contained in:
Bjorn Terelius
2018-10-11 16:51:23 +02:00
committed by Commit Bot
parent 499bc6c5d0
commit 5350d1cafd
15 changed files with 150 additions and 120 deletions

View File

@ -19,11 +19,8 @@ namespace webrtc {
namespace test {
NetEqEventLogInput::NetEqEventLogInput(const std::string& file_name,
const RtpHeaderExtensionMap& hdr_ext_map)
: source_(RtcEventLogSource::Create(file_name)) {
for (const auto& ext_pair : hdr_ext_map) {
source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first);
}
absl::optional<uint32_t> ssrc_filter)
: source_(RtcEventLogSource::Create(file_name, ssrc_filter)) {
LoadNextPacket();
AdvanceOutputEvent();
}

View File

@ -28,7 +28,7 @@ class RtcEventLogSource;
class NetEqEventLogInput final : public NetEqPacketSourceInput {
public:
NetEqEventLogInput(const std::string& file_name,
const RtpHeaderExtensionMap& hdr_ext_map);
absl::optional<uint32_t> ssrc_filter);
absl::optional<int64_t> NextOutputEventTime() const override;
void AdvanceOutputEvent() override;

View File

@ -58,15 +58,10 @@ std::unique_ptr<NetEqInput::PacketData> NetEqPacketSourceInput::PopPacket() {
return packet_data;
}
void NetEqPacketSourceInput::SelectSsrc(uint32_t ssrc) {
source()->SelectSsrc(ssrc);
if (packet_ && packet_->header().ssrc != ssrc)
LoadNextPacket();
}
NetEqRtpDumpInput::NetEqRtpDumpInput(const std::string& file_name,
const RtpHeaderExtensionMap& hdr_ext_map)
: source_(RtpFileSource::Create(file_name)) {
const RtpHeaderExtensionMap& hdr_ext_map,
absl::optional<uint32_t> ssrc_filter)
: source_(RtpFileSource::Create(file_name, ssrc_filter)) {
for (const auto& ext_pair : hdr_ext_map) {
source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first);
}

View File

@ -12,8 +12,10 @@
#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PACKET_SOURCE_INPUT_H_
#include <map>
#include <memory>
#include <string>
#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tools/neteq_input.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -32,7 +34,6 @@ class NetEqPacketSourceInput : public NetEqInput {
std::unique_ptr<PacketData> PopPacket() override;
absl::optional<RTPHeader> NextHeader() const override;
bool ended() const override { return !next_output_event_ms_; }
void SelectSsrc(uint32_t);
protected:
virtual PacketSource* source() = 0;
@ -48,7 +49,8 @@ class NetEqPacketSourceInput : public NetEqInput {
class NetEqRtpDumpInput final : public NetEqPacketSourceInput {
public:
NetEqRtpDumpInput(const std::string& file_name,
const RtpHeaderExtensionMap& hdr_ext_map);
const RtpHeaderExtensionMap& hdr_ext_map,
absl::optional<uint32_t> ssrc_filter);
absl::optional<int64_t> NextOutputEventTime() const override;
void AdvanceOutputEvent() override;

View File

@ -309,25 +309,27 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
{FLAG_video_content_type, kRtpExtensionVideoContentType},
{FLAG_video_timing, kRtpExtensionVideoTiming}};
absl::optional<uint32_t> ssrc_filter;
// Check if an SSRC value was provided.
if (strlen(FLAG_ssrc) > 0) {
uint32_t ssrc;
RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed.";
ssrc_filter = ssrc;
}
std::unique_ptr<NetEqInput> input;
if (RtpFileSource::ValidRtpDump(input_file_name) ||
RtpFileSource::ValidPcap(input_file_name)) {
input.reset(new NetEqRtpDumpInput(input_file_name, rtp_ext_map));
input.reset(
new NetEqRtpDumpInput(input_file_name, rtp_ext_map, ssrc_filter));
} else {
input.reset(new NetEqEventLogInput(input_file_name, rtp_ext_map));
input.reset(new NetEqEventLogInput(input_file_name, ssrc_filter));
}
std::cout << "Input file: " << input_file_name << std::endl;
RTC_CHECK(input) << "Cannot open input file";
RTC_CHECK(!input->ended()) << "Input file is empty";
// Check if an SSRC value was provided.
if (strlen(FLAG_ssrc) > 0) {
uint32_t ssrc;
RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed.";
static_cast<NetEqPacketSourceInput*>(input.get())->SelectSsrc(ssrc);
}
// Check the sample rate.
absl::optional<int> sample_rate_hz;
std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;

View File

@ -49,6 +49,20 @@ Packet::Packet(uint8_t* packet_memory,
valid_header_ = ParseHeader(parser);
}
Packet::Packet(const RTPHeader& header,
size_t virtual_packet_length_bytes,
size_t virtual_payload_length_bytes,
double time_ms)
: header_(header),
payload_memory_(),
payload_(NULL),
packet_length_bytes_(0),
payload_length_bytes_(0),
virtual_packet_length_bytes_(virtual_packet_length_bytes),
virtual_payload_length_bytes_(virtual_payload_length_bytes),
time_ms_(time_ms),
valid_header_(true) {}
Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
: payload_memory_(packet_memory),
payload_(NULL),

View File

@ -50,7 +50,17 @@ class Packet {
double time_ms,
const RtpHeaderParser& parser);
// The following two constructors are the same as above, but without a
// Same as above, but creates the packet from an already parsed RTPHeader.
// This is typically used when reading RTP dump files that only contain the
// RTP headers, and no payload. The |virtual_packet_length_bytes| tells what
// size the packet had on wire, including the now discarded payload,
// The |virtual_payload_length_bytes| tells the size of the payload.
Packet(const RTPHeader& header,
size_t virtual_packet_length_bytes,
size_t virtual_payload_length_bytes,
double time_ms);
// The following constructors are the same as the first two, but without a
// parser. Note that when the object is constructed using any of these
// methods, the header will be parsed using a default RtpHeaderParser object.
// In particular, RTP header extensions won't be parsed.

View File

@ -13,7 +13,7 @@
namespace webrtc {
namespace test {
PacketSource::PacketSource() : use_ssrc_filter_(false), ssrc_(0) {}
PacketSource::PacketSource() = default;
PacketSource::~PacketSource() = default;
@ -21,10 +21,5 @@ void PacketSource::FilterOutPayloadType(uint8_t payload_type) {
filter_.set(payload_type, true);
}
void PacketSource::SelectSsrc(uint32_t ssrc) {
use_ssrc_filter_ = true;
ssrc_ = ssrc;
}
} // namespace test
} // namespace webrtc

View File

@ -32,13 +32,8 @@ class PacketSource {
virtual void FilterOutPayloadType(uint8_t payload_type);
virtual void SelectSsrc(uint32_t 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:
RTC_DISALLOW_COPY_AND_ASSIGN(PacketSource);

View File

@ -13,94 +13,105 @@
#include <string.h>
#include <iostream>
#include <limits>
#include <utility>
#include "logging/rtc_event_log/rtc_event_processor.h"
#include "modules/audio_coding/neteq/tools/packet.h"
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace test {
RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) {
namespace {
bool ShouldSkipStream(ParsedRtcEventLogNew::MediaType media_type,
uint32_t ssrc,
absl::optional<uint32_t> ssrc_filter) {
if (media_type != ParsedRtcEventLogNew::MediaType::AUDIO)
return true;
if (ssrc_filter.has_value() && ssrc != *ssrc_filter)
return true;
return false;
}
} // namespace
RtcEventLogSource* RtcEventLogSource::Create(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
RtcEventLogSource* source = new RtcEventLogSource();
RTC_CHECK(source->OpenFile(file_name));
RTC_CHECK(source->OpenFile(file_name, ssrc_filter));
return source;
}
RtcEventLogSource::~RtcEventLogSource() {}
bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) {
RTC_CHECK(parser_.get());
return parser_->RegisterRtpHeaderExtension(type, id);
}
std::unique_ptr<Packet> RtcEventLogSource::NextPacket() {
for (; rtp_packet_index_ < parsed_stream_.GetNumberOfEvents();
rtp_packet_index_++) {
if (parsed_stream_.GetEventType(rtp_packet_index_) ==
ParsedRtcEventLogNew::EventType::RTP_EVENT) {
PacketDirection direction;
size_t header_length;
size_t packet_length;
uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_);
parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, nullptr,
&header_length, &packet_length, nullptr);
if (rtp_packet_index_ >= rtp_packets_.size())
return nullptr;
if (direction != kIncomingPacket) {
continue;
}
uint8_t* packet_header = new uint8_t[header_length];
parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, packet_header,
nullptr, nullptr, nullptr);
std::unique_ptr<Packet> packet(
new Packet(packet_header, header_length, packet_length,
static_cast<double>(timestamp_us) / 1000, *parser_.get()));
if (!packet->valid_header()) {
std::cout << "Warning: Packet with index " << rtp_packet_index_
<< " has an invalid header and will be ignored." << std::endl;
continue;
}
if (parsed_stream_.GetMediaType(packet->header().ssrc, direction) !=
ParsedRtcEventLogNew::MediaType::AUDIO) {
continue;
}
// Check if the packet should not be filtered out.
if (!filter_.test(packet->header().payloadType) &&
!(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) {
++rtp_packet_index_;
return packet;
}
}
}
return nullptr;
std::unique_ptr<Packet> packet = std::move(rtp_packets_[rtp_packet_index_++]);
return packet;
}
int64_t RtcEventLogSource::NextAudioOutputEventMs() {
while (audio_output_index_ < parsed_stream_.GetNumberOfEvents()) {
if (parsed_stream_.GetEventType(audio_output_index_) ==
ParsedRtcEventLogNew::EventType::AUDIO_PLAYOUT_EVENT) {
LoggedAudioPlayoutEvent playout_event =
parsed_stream_.GetAudioPlayout(audio_output_index_);
if (!(use_ssrc_filter_ && playout_event.ssrc != ssrc_)) {
audio_output_index_++;
return playout_event.timestamp_us / 1000;
}
}
audio_output_index_++;
}
return std::numeric_limits<int64_t>::max();
if (audio_output_index_ >= audio_outputs_.size())
return std::numeric_limits<int64_t>::max();
int64_t output_time_ms = audio_outputs_[audio_output_index_++];
return output_time_ms;
}
RtcEventLogSource::RtcEventLogSource()
: PacketSource(), parser_(RtpHeaderParser::Create()) {}
RtcEventLogSource::RtcEventLogSource() : PacketSource() {}
bool RtcEventLogSource::OpenFile(const std::string& file_name) {
return parsed_stream_.ParseFile(file_name);
bool RtcEventLogSource::OpenFile(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
ParsedRtcEventLogNew parsed_log;
if (!parsed_log.ParseFile(file_name))
return false;
auto handle_rtp_packet =
[this](const webrtc::LoggedRtpPacketIncoming& incoming) {
if (!filter_.test(incoming.rtp.header.payloadType)) {
rtp_packets_.emplace_back(absl::make_unique<Packet>(
incoming.rtp.header, incoming.rtp.total_length,
incoming.rtp.total_length - incoming.rtp.header_length,
static_cast<double>(incoming.log_time_ms())));
}
};
auto handle_audio_playout =
[this](const webrtc::LoggedAudioPlayoutEvent& audio_playout) {
audio_outputs_.emplace_back(audio_playout.log_time_ms());
};
// This wouldn't be needed if we knew that there was at most one audio stream.
webrtc::RtcEventProcessor event_processor;
for (const auto& rtp_packets : parsed_log.incoming_rtp_packets_by_ssrc()) {
ParsedRtcEventLogNew::MediaType media_type =
parsed_log.GetMediaType(rtp_packets.ssrc, webrtc::kIncomingPacket);
if (ShouldSkipStream(media_type, rtp_packets.ssrc, ssrc_filter)) {
continue;
}
auto rtp_view = absl::make_unique<
webrtc::ProcessableEventList<webrtc::LoggedRtpPacketIncoming>>(
rtp_packets.incoming_packets.begin(),
rtp_packets.incoming_packets.end(), handle_rtp_packet);
event_processor.AddEvents(std::move(rtp_view));
}
for (const auto& audio_playouts : parsed_log.audio_playout_events()) {
if (ssrc_filter.has_value() && audio_playouts.first != *ssrc_filter)
continue;
auto audio_view = absl::make_unique<
webrtc::ProcessableEventList<webrtc::LoggedAudioPlayoutEvent>>(
audio_playouts.second.begin(), audio_playouts.second.end(),
handle_audio_playout);
event_processor.AddEvents(std::move(audio_view));
}
// Fills in rtp_packets_ and audio_outputs_.
event_processor.ProcessEventsInOrder();
return true;
}
} // namespace test

View File

@ -13,7 +13,9 @@
#include <memory>
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "logging/rtc_event_log/rtc_event_log_parser_new.h"
#include "modules/audio_coding/neteq/tools/packet_source.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -31,13 +33,11 @@ class RtcEventLogSource : public PacketSource {
public:
// Creates an RtcEventLogSource reading from |file_name|. If the file cannot
// be opened, or has the wrong format, NULL will be returned.
static RtcEventLogSource* Create(const std::string& file_name);
static RtcEventLogSource* Create(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
virtual ~RtcEventLogSource();
// Registers an RTP header extension and binds it to |id|.
virtual bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
std::unique_ptr<Packet> NextPacket() override;
// Returns the timestamp of the next audio output event, in milliseconds. The
@ -48,14 +48,14 @@ class RtcEventLogSource : public PacketSource {
private:
RtcEventLogSource();
bool OpenFile(const std::string& file_name);
bool OpenFile(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
std::vector<std::unique_ptr<Packet>> rtp_packets_;
size_t rtp_packet_index_ = 0;
std::vector<int64_t> audio_outputs_;
size_t audio_output_index_ = 0;
ParsedRtcEventLogNew parsed_stream_;
std::unique_ptr<RtpHeaderParser> parser_;
RTC_DISALLOW_COPY_AND_ASSIGN(RtcEventLogSource);
};

View File

@ -26,8 +26,9 @@
namespace webrtc {
namespace test {
RtpFileSource* RtpFileSource::Create(const std::string& file_name) {
RtpFileSource* source = new RtpFileSource();
RtpFileSource* RtpFileSource::Create(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
RtpFileSource* source = new RtpFileSource(ssrc_filter);
RTC_CHECK(source->OpenFile(file_name));
return source;
}
@ -72,7 +73,7 @@ std::unique_ptr<Packet> RtpFileSource::NextPacket() {
continue;
}
if (filter_.test(packet->header().payloadType) ||
(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) {
(ssrc_filter_ && packet->header().ssrc != *ssrc_filter_)) {
// This payload type should be filtered out. Continue to the next packet.
continue;
}
@ -80,8 +81,10 @@ std::unique_ptr<Packet> RtpFileSource::NextPacket() {
}
}
RtpFileSource::RtpFileSource()
: PacketSource(), parser_(RtpHeaderParser::Create()) {}
RtpFileSource::RtpFileSource(absl::optional<uint32_t> ssrc_filter)
: PacketSource(),
parser_(RtpHeaderParser::Create()),
ssrc_filter_(ssrc_filter) {}
bool RtpFileSource::OpenFile(const std::string& file_name) {
rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kRtpDump, file_name));

View File

@ -16,6 +16,7 @@
#include <memory>
#include <string>
#include "absl/types/optional.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/neteq/tools/packet_source.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -33,7 +34,9 @@ class RtpFileSource : public PacketSource {
public:
// Creates an RtpFileSource reading from |file_name|. If the file cannot be
// opened, or has the wrong format, NULL will be returned.
static RtpFileSource* Create(const std::string& file_name);
static RtpFileSource* Create(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter = absl::nullopt);
// Checks whether a files is a valid RTP dump or PCAP (Wireshark) file.
static bool ValidRtpDump(const std::string& file_name);
@ -51,12 +54,13 @@ class RtpFileSource : public PacketSource {
static const int kRtpFileHeaderSize = 4 + 4 + 4 + 2 + 2;
static const size_t kPacketHeaderSize = 8;
RtpFileSource();
explicit RtpFileSource(absl::optional<uint32_t> ssrc_filter);
bool OpenFile(const std::string& file_name);
std::unique_ptr<RtpFileReader> rtp_reader_;
std::unique_ptr<RtpHeaderParser> parser_;
const absl::optional<uint32_t> ssrc_filter_;
RTC_DISALLOW_COPY_AND_ASSIGN(RtpFileSource);
};