webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc
Ivo Creusen 94f107454e Only use GetAudio events that correspond to an ssrc matching at least one incoming packet.
Using GetAudio events from SSRCs without incoming packets doesn't make sense, and should be prevented.

Bug: b/116685514
Change-Id: I48e38bb780549c71cb5f68d370a6819634ad487d
Reviewed-on: https://webrtc-review.googlesource.com/c/114321
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26017}
2018-12-14 15:05:15 +00:00

142 lines
4.9 KiB
C++

/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_coding/neteq/tools/rtc_event_log_source.h"
#include <string.h>
#include <iostream>
#include <limits>
#include <set>
#include <utility>
#include "logging/rtc_event_log/rtc_event_processor.h"
#include "modules/audio_coding/neteq/tools/packet.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace test {
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, ssrc_filter));
return source;
}
RtcEventLogSource::~RtcEventLogSource() {}
std::unique_ptr<Packet> RtcEventLogSource::NextPacket() {
if (rtp_packet_index_ >= rtp_packets_.size())
return nullptr;
std::unique_ptr<Packet> packet = std::move(rtp_packets_[rtp_packet_index_++]);
return packet;
}
int64_t RtcEventLogSource::NextAudioOutputEventMs() {
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() {}
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;
const auto first_log_end_time_us =
parsed_log.stop_log_events().empty()
? std::numeric_limits<int64_t>::max()
: parsed_log.stop_log_events().front().log_time_us();
std::set<uint32_t> packet_ssrcs;
auto handle_rtp_packet =
[this, first_log_end_time_us,
&packet_ssrcs](const webrtc::LoggedRtpPacketIncoming& incoming) {
if (!filter_.test(incoming.rtp.header.payloadType) &&
incoming.log_time_us() < first_log_end_time_us) {
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())));
packet_ssrcs.insert(rtp_packets_.back()->header().ssrc);
}
};
std::set<uint32_t> ignored_ssrcs;
auto handle_audio_playout =
[this, first_log_end_time_us, &packet_ssrcs,
&ignored_ssrcs](const webrtc::LoggedAudioPlayoutEvent& audio_playout) {
if (audio_playout.log_time_us() < first_log_end_time_us) {
if (packet_ssrcs.count(audio_playout.ssrc) > 0) {
audio_outputs_.emplace_back(audio_playout.log_time_ms());
} else {
ignored_ssrcs.insert(audio_playout.ssrc);
}
}
};
// 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();
for (const auto& ssrc : ignored_ssrcs) {
std::cout << "Ignoring GetAudio events from SSRC 0x" << std::hex << ssrc
<< " because no packets were found with a matching SSRC."
<< std::endl;
}
return true;
}
} // namespace test
} // namespace webrtc