mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
Add RtcEvent to store when MinimumSetDelay is set on NetEq
To be able to simulate offline some scenario in which the javascript layer set the minimum base buffer size of neteq, it is required to record those API calls. This change introduces this. Bug: webrtc:14763 Change-Id: Ic817913eda60978d6fca3f8e12229aeec505ca25 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/287122 Auto-Submit: Lionel Koenig <lionelk@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Lionel Koenig <lionelk@webrtc.org> Reviewed-by: Per Åhgren <peah@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39104}
This commit is contained in:
parent
8da0f3aecc
commit
612872b29d
14 changed files with 370 additions and 1 deletions
|
@ -54,6 +54,7 @@ class RtcEvent {
|
|||
GenericPacketReceived,
|
||||
GenericAckReceived,
|
||||
FrameDecoded,
|
||||
NetEqSetMinimumDelay,
|
||||
BeginV3Log = 0x2501580,
|
||||
EndV3Log = 0x2501581,
|
||||
FakeEvent, // For unit testing.
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "audio/channel_send.h"
|
||||
#include "audio/utility/audio_frame_operations.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
|
@ -1017,6 +1018,8 @@ ChannelReceive::GetCurrentEstimatedPlayoutNtpTimestampMs(int64_t now_ms) const {
|
|||
}
|
||||
|
||||
bool ChannelReceive::SetBaseMinimumPlayoutDelayMs(int delay_ms) {
|
||||
event_log_->Log(
|
||||
std::make_unique<RtcEventNetEqSetMinimumDelay>(remote_ssrc_, delay_ms));
|
||||
return acm_receiver_.SetBaseMinimumDelayMs(delay_ms);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ rtc_library("rtc_event_audio") {
|
|||
"rtc_event_log/events/rtc_event_audio_receive_stream_config.h",
|
||||
"rtc_event_log/events/rtc_event_audio_send_stream_config.cc",
|
||||
"rtc_event_log/events/rtc_event_audio_send_stream_config.h",
|
||||
"rtc_event_log/events/rtc_event_neteq_set_minimum_delay.cc",
|
||||
"rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
|
@ -306,6 +308,7 @@ rtc_library("rtc_event_log_impl_encoder") {
|
|||
"../rtc_base:ignore_wundef",
|
||||
"../rtc_base:logging",
|
||||
"../rtc_base:safe_conversions",
|
||||
"../system_wrappers:field_trial",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
|
|
|
@ -383,6 +383,7 @@ std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
|
|||
case RtcEvent::Type::GenericPacketSent:
|
||||
case RtcEvent::Type::GenericAckReceived:
|
||||
case RtcEvent::Type::FrameDecoded:
|
||||
case RtcEvent::Type::NetEqSetMinimumDelay:
|
||||
// These are unsupported in the old format, but shouldn't crash.
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
|
||||
|
@ -60,6 +61,7 @@
|
|||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/ignore_wundef.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "system_wrappers/include/field_trial.h"
|
||||
|
||||
// *.pb.h files are generated at build-time by the protobuf compiler.
|
||||
RTC_PUSH_IGNORING_WUNDEF()
|
||||
|
@ -652,6 +654,14 @@ void EncodeRtpPacket(const std::vector<const EventType*>& batch,
|
|||
}
|
||||
} // namespace
|
||||
|
||||
RtcEventLogEncoderNewFormat::RtcEventLogEncoderNewFormat() {
|
||||
encode_neteq_set_minimum_delay_kill_switch_ = false;
|
||||
if (webrtc::field_trial::IsEnabled(
|
||||
"WebRTC-RtcEventLogEncodeNetEqSetMinimumDelayKillSwitch")) {
|
||||
encode_neteq_set_minimum_delay_kill_switch_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderNewFormat::EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) {
|
||||
rtclog2::EventStream event_stream;
|
||||
|
@ -680,6 +690,8 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
|
|||
std::vector<const RtcEventAudioNetworkAdaptation*>
|
||||
audio_network_adaptation_events;
|
||||
std::vector<const RtcEventAudioPlayout*> audio_playout_events;
|
||||
std::vector<const RtcEventNetEqSetMinimumDelay*>
|
||||
neteq_set_minimum_delay_events;
|
||||
std::vector<const RtcEventAudioReceiveStreamConfig*>
|
||||
audio_recv_stream_configs;
|
||||
std::vector<const RtcEventAudioSendStreamConfig*> audio_send_stream_configs;
|
||||
|
@ -877,6 +889,12 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
|
|||
frames_decoded[rtc_event->ssrc()].emplace_back(rtc_event);
|
||||
break;
|
||||
}
|
||||
case RtcEvent::Type::NetEqSetMinimumDelay: {
|
||||
auto* rtc_event =
|
||||
static_cast<const RtcEventNetEqSetMinimumDelay* const>(it->get());
|
||||
neteq_set_minimum_delay_events.push_back(rtc_event);
|
||||
break;
|
||||
}
|
||||
case RtcEvent::Type::BeginV3Log:
|
||||
case RtcEvent::Type::EndV3Log:
|
||||
// These special events are written as part of starting
|
||||
|
@ -896,6 +914,7 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
|
|||
EncodeAudioPlayout(audio_playout_events, &event_stream);
|
||||
EncodeAudioRecvStreamConfig(audio_recv_stream_configs, &event_stream);
|
||||
EncodeAudioSendStreamConfig(audio_send_stream_configs, &event_stream);
|
||||
EncodeNetEqSetMinimumDelay(neteq_set_minimum_delay_events, &event_stream);
|
||||
EncodeBweUpdateDelayBased(bwe_delay_based_updates, &event_stream);
|
||||
EncodeBweUpdateLossBased(bwe_loss_based_updates, &event_stream);
|
||||
EncodeDtlsTransportState(dtls_transport_states, &event_stream);
|
||||
|
@ -1129,6 +1148,64 @@ void RtcEventLogEncoderNewFormat::EncodeAudioPlayout(
|
|||
}
|
||||
}
|
||||
|
||||
void RtcEventLogEncoderNewFormat::EncodeNetEqSetMinimumDelay(
|
||||
rtc::ArrayView<const RtcEventNetEqSetMinimumDelay*> batch,
|
||||
rtclog2::EventStream* event_stream) {
|
||||
if (encode_neteq_set_minimum_delay_kill_switch_) {
|
||||
return;
|
||||
}
|
||||
if (batch.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const RtcEventNetEqSetMinimumDelay* base_event = batch[0];
|
||||
|
||||
rtclog2::NetEqSetMinimumDelay* proto_batch =
|
||||
event_stream->add_neteq_set_minimum_delay();
|
||||
proto_batch->set_timestamp_ms(base_event->timestamp_ms());
|
||||
proto_batch->set_remote_ssrc(base_event->remote_ssrc());
|
||||
proto_batch->set_minimum_delay_ms(base_event->minimum_delay_ms());
|
||||
|
||||
if (batch.size() == 1)
|
||||
return;
|
||||
|
||||
// Delta encoding
|
||||
proto_batch->set_number_of_deltas(batch.size() - 1);
|
||||
std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
|
||||
std::string encoded_deltas;
|
||||
|
||||
// timestamp_ms
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
const RtcEventNetEqSetMinimumDelay* event = batch[i + 1];
|
||||
values[i] = ToUnsigned(event->timestamp_ms());
|
||||
}
|
||||
encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
proto_batch->set_timestamp_ms_deltas(encoded_deltas);
|
||||
}
|
||||
|
||||
// remote_ssrc
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
const RtcEventNetEqSetMinimumDelay* event = batch[i + 1];
|
||||
values[i] = event->remote_ssrc();
|
||||
}
|
||||
encoded_deltas = EncodeDeltas(base_event->remote_ssrc(), values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
proto_batch->set_remote_ssrc_deltas(encoded_deltas);
|
||||
}
|
||||
|
||||
// minimum_delay_ms
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
const RtcEventNetEqSetMinimumDelay* event = batch[i + 1];
|
||||
values[i] = ToUnsigned(event->minimum_delay_ms());
|
||||
}
|
||||
encoded_deltas =
|
||||
EncodeDeltas(ToUnsigned(base_event->minimum_delay_ms()), values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
proto_batch->set_minimum_delay_ms_deltas(encoded_deltas);
|
||||
}
|
||||
}
|
||||
|
||||
void RtcEventLogEncoderNewFormat::EncodeAudioRecvStreamConfig(
|
||||
rtc::ArrayView<const RtcEventAudioReceiveStreamConfig*> batch,
|
||||
rtclog2::EventStream* event_stream) {
|
||||
|
|
|
@ -39,6 +39,7 @@ class RtcEventDtlsTransportState;
|
|||
class RtcEventDtlsWritableState;
|
||||
class RtcEventLoggingStarted;
|
||||
class RtcEventLoggingStopped;
|
||||
class RtcEventNetEqSetMinimumDelay;
|
||||
class RtcEventProbeClusterCreated;
|
||||
class RtcEventProbeResultFailure;
|
||||
class RtcEventProbeResultSuccess;
|
||||
|
@ -58,6 +59,7 @@ class RtcEventGenericPacketSent;
|
|||
|
||||
class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
|
||||
public:
|
||||
RtcEventLogEncoderNewFormat();
|
||||
~RtcEventLogEncoderNewFormat() override = default;
|
||||
|
||||
std::string EncodeBatch(
|
||||
|
@ -69,6 +71,8 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
|
|||
std::string EncodeLogEnd(int64_t timestamp_us) override;
|
||||
|
||||
private:
|
||||
bool encode_neteq_set_minimum_delay_kill_switch_ = false;
|
||||
|
||||
// Encoding entry-point for the various RtcEvent subclasses.
|
||||
void EncodeAlrState(rtc::ArrayView<const RtcEventAlrState*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
|
@ -117,6 +121,9 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
|
|||
rtclog2::EventStream* event_stream);
|
||||
void EncodeLoggingStopped(rtc::ArrayView<const RtcEventLoggingStopped*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeNetEqSetMinimumDelay(
|
||||
rtc::ArrayView<const RtcEventNetEqSetMinimumDelay*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeProbeClusterCreated(
|
||||
rtc::ArrayView<const RtcEventProbeClusterCreated*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
|
|
|
@ -441,6 +441,64 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(RtcEventLogEncoderTest, RtcEventNetEqSetMinimumDelayDecoded) {
|
||||
// SSRCs will be randomly assigned out of this small pool, significant only
|
||||
// in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff.
|
||||
// The pool is intentionally small, so as to produce collisions.
|
||||
const std::vector<uint32_t> kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01,
|
||||
0xffffffff, 0x20171024, 0x19840730,
|
||||
0x19831230};
|
||||
std::map<uint32_t, std::vector<std::unique_ptr<RtcEventNetEqSetMinimumDelay>>>
|
||||
original_events_by_ssrc;
|
||||
for (size_t i = 0; i < event_count_; ++i) {
|
||||
const uint32_t ssrc = kSsrcPool[prng_.Rand(kSsrcPool.size() - 1)];
|
||||
std::unique_ptr<RtcEventNetEqSetMinimumDelay> event =
|
||||
(original_events_by_ssrc[ssrc].empty() || !force_repeated_fields_)
|
||||
? gen_.NewNetEqSetMinimumDelay(ssrc)
|
||||
: original_events_by_ssrc[ssrc][0]->Copy();
|
||||
history_.push_back(event->Copy());
|
||||
original_events_by_ssrc[ssrc].push_back(std::move(event));
|
||||
}
|
||||
|
||||
encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
|
||||
ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
|
||||
|
||||
const auto& parsed_neteq_set_minimum_delay_events_by_ssrc =
|
||||
parsed_log_.neteq_set_minimum_delay_events();
|
||||
|
||||
if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
|
||||
ASSERT_EQ(parsed_neteq_set_minimum_delay_events_by_ssrc.size(), 0u);
|
||||
return;
|
||||
}
|
||||
|
||||
// Same number of distinct SSRCs.
|
||||
ASSERT_EQ(parsed_neteq_set_minimum_delay_events_by_ssrc.size(),
|
||||
original_events_by_ssrc.size());
|
||||
|
||||
for (auto& original_event_it : original_events_by_ssrc) {
|
||||
const uint32_t ssrc = original_event_it.first;
|
||||
const auto& original_neteq_set_minimum_delay_events =
|
||||
original_event_it.second;
|
||||
|
||||
const auto& parsed_event_it =
|
||||
parsed_neteq_set_minimum_delay_events_by_ssrc.find(ssrc);
|
||||
ASSERT_TRUE(parsed_event_it !=
|
||||
parsed_neteq_set_minimum_delay_events_by_ssrc.end());
|
||||
const auto& parsed_neteq_set_minimum_delay_events = parsed_event_it->second;
|
||||
|
||||
// Same number playout events for the SSRC under examination.
|
||||
ASSERT_EQ(original_neteq_set_minimum_delay_events.size(),
|
||||
parsed_neteq_set_minimum_delay_events.size());
|
||||
|
||||
for (size_t i = 0; i < original_neteq_set_minimum_delay_events.size();
|
||||
++i) {
|
||||
verifier_.VerifyLoggedNetEqSetMinimumDelay(
|
||||
*original_neteq_set_minimum_delay_events[i],
|
||||
parsed_neteq_set_minimum_delay_events[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(eladalon/terelius): Test with multiple events in the batch.
|
||||
TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) {
|
||||
uint32_t ssrc = prng_.Rand<uint32_t>();
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_definition.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventNetEqSetMinimumDelay::RtcEventNetEqSetMinimumDelay(uint32_t remote_ssrc,
|
||||
int delay_ms)
|
||||
: remote_ssrc_(remote_ssrc), minimum_delay_ms_(delay_ms) {}
|
||||
RtcEventNetEqSetMinimumDelay::~RtcEventNetEqSetMinimumDelay() {}
|
||||
|
||||
} // namespace webrtc
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_definition.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedNetEqSetMinimumDelayEvent {
|
||||
LoggedNetEqSetMinimumDelayEvent() = default;
|
||||
LoggedNetEqSetMinimumDelayEvent(Timestamp timestamp,
|
||||
uint32_t remote_ssrc,
|
||||
int minimum_delay_ms)
|
||||
: timestamp(timestamp),
|
||||
remote_ssrc(remote_ssrc),
|
||||
minimum_delay_ms(minimum_delay_ms) {}
|
||||
|
||||
int64_t log_time_us() const { return timestamp.us(); }
|
||||
int64_t log_time_ms() const { return timestamp.ms(); }
|
||||
Timestamp log_time() const { return timestamp; }
|
||||
|
||||
Timestamp timestamp = Timestamp::MinusInfinity();
|
||||
uint32_t remote_ssrc;
|
||||
int minimum_delay_ms;
|
||||
};
|
||||
|
||||
class RtcEventNetEqSetMinimumDelay final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::NetEqSetMinimumDelay;
|
||||
|
||||
explicit RtcEventNetEqSetMinimumDelay(uint32_t remote_ssrc, int delay_ms);
|
||||
~RtcEventNetEqSetMinimumDelay() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
uint32_t remote_ssrc() const { return remote_ssrc_; }
|
||||
int minimum_delay_ms() const { return minimum_delay_ms_; }
|
||||
|
||||
std::unique_ptr<RtcEventNetEqSetMinimumDelay> Copy() const {
|
||||
return absl::WrapUnique<RtcEventNetEqSetMinimumDelay>(
|
||||
new RtcEventNetEqSetMinimumDelay(*this));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t remote_ssrc_;
|
||||
int minimum_delay_ms_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
|
|
@ -40,6 +40,7 @@ message EventStream {
|
|||
repeated GenericAckReceived generic_acks_received = 31;
|
||||
repeated RouteChange route_changes = 32;
|
||||
repeated RemoteEstimates remote_estimates = 33;
|
||||
repeated NetEqSetMinimumDelay neteq_set_minimum_delay = 34;
|
||||
|
||||
repeated AudioRecvStreamConfig audio_recv_stream_configs = 101;
|
||||
repeated AudioSendStreamConfig audio_send_stream_configs = 102;
|
||||
|
@ -285,6 +286,26 @@ message AudioPlayoutEvents {
|
|||
optional bytes local_ssrc_deltas = 102;
|
||||
}
|
||||
|
||||
message NetEqSetMinimumDelay {
|
||||
// required
|
||||
optional int64 timestamp_ms = 1;
|
||||
|
||||
// required - The SSRC of the remote stream associated with the MinimumDelay
|
||||
// event.
|
||||
optional fixed32 remote_ssrc = 2;
|
||||
|
||||
// required - minimum delay passed to SetBaseMinimumDelay.
|
||||
optional int32 minimum_delay_ms = 3;
|
||||
|
||||
// optional - required if the batch contains delta encoded events.
|
||||
optional uint32 number_of_deltas = 4;
|
||||
|
||||
// Delta encodings.
|
||||
optional bytes timestamp_ms_deltas = 101;
|
||||
optional bytes remote_ssrc_deltas = 102;
|
||||
optional bytes minimum_delay_ms_deltas = 103;
|
||||
}
|
||||
|
||||
message FrameDecodedEvents {
|
||||
enum Codec {
|
||||
CODEC_UNKNOWN = 0;
|
||||
|
|
|
@ -1086,6 +1086,7 @@ void ParsedRtcEventLog::Clear() {
|
|||
start_log_events_.clear();
|
||||
stop_log_events_.clear();
|
||||
audio_playout_events_.clear();
|
||||
neteq_set_minimum_delay_events_.clear();
|
||||
audio_network_adaptation_events_.clear();
|
||||
bwe_probe_cluster_created_events_.clear();
|
||||
bwe_probe_failure_events_.clear();
|
||||
|
@ -1235,6 +1236,10 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream(
|
|||
// Audio playout events are grouped by SSRC.
|
||||
StoreFirstAndLastTimestamp(audio_stream.second);
|
||||
}
|
||||
for (const auto& set_minimum_delay : neteq_set_minimum_delay_events()) {
|
||||
// NetEq SetMinimumDelay grouped by SSRC.
|
||||
StoreFirstAndLastTimestamp(set_minimum_delay.second);
|
||||
}
|
||||
StoreFirstAndLastTimestamp(audio_network_adaptation_events());
|
||||
StoreFirstAndLastTimestamp(bwe_probe_cluster_created_events());
|
||||
StoreFirstAndLastTimestamp(bwe_probe_failure_events());
|
||||
|
@ -2522,7 +2527,8 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedNewFormatEvent(
|
|||
stream.generic_packets_sent_size() +
|
||||
stream.generic_packets_received_size() +
|
||||
stream.generic_acks_received_size() +
|
||||
stream.frame_decoded_events_size(),
|
||||
stream.frame_decoded_events_size() +
|
||||
stream.neteq_set_minimum_delay_size(),
|
||||
1u);
|
||||
|
||||
if (stream.incoming_rtp_packets_size() == 1) {
|
||||
|
@ -2582,6 +2588,8 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedNewFormatEvent(
|
|||
return StoreGenericAckReceivedEvent(stream.generic_acks_received(0));
|
||||
} else if (stream.frame_decoded_events_size() == 1) {
|
||||
return StoreFrameDecodedEvents(stream.frame_decoded_events(0));
|
||||
} else if (stream.neteq_set_minimum_delay_size() == 1) {
|
||||
return StoreNetEqSetMinimumDelay(stream.neteq_set_minimum_delay(0));
|
||||
} else {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return ParseStatus::Success();
|
||||
|
@ -2726,6 +2734,65 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreAudioPlayoutEvent(
|
|||
return ParseStatus::Success();
|
||||
}
|
||||
|
||||
ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreNetEqSetMinimumDelay(
|
||||
const rtclog2::NetEqSetMinimumDelay& proto) {
|
||||
RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
|
||||
RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
|
||||
RTC_PARSE_CHECK_OR_RETURN(proto.has_minimum_delay_ms());
|
||||
|
||||
// Base event
|
||||
neteq_set_minimum_delay_events_[proto.remote_ssrc()].emplace_back(
|
||||
Timestamp::Millis(proto.timestamp_ms()), proto.remote_ssrc(),
|
||||
static_cast<int>(proto.minimum_delay_ms()));
|
||||
|
||||
const size_t number_of_deltas =
|
||||
proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
|
||||
if (number_of_deltas == 0) {
|
||||
return ParseStatus::Success();
|
||||
}
|
||||
|
||||
// timestamp_ms
|
||||
std::vector<absl::optional<uint64_t>> timestamp_ms_values =
|
||||
DecodeDeltas(proto.timestamp_ms_deltas(),
|
||||
ToUnsigned(proto.timestamp_ms()), number_of_deltas);
|
||||
RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
|
||||
|
||||
// remote_ssrc
|
||||
std::vector<absl::optional<uint64_t>> remote_ssrc_values = DecodeDeltas(
|
||||
proto.remote_ssrc_deltas(), proto.remote_ssrc(), number_of_deltas);
|
||||
RTC_PARSE_CHECK_OR_RETURN_EQ(remote_ssrc_values.size(), number_of_deltas);
|
||||
|
||||
// minimum_delay_ms
|
||||
std::vector<absl::optional<uint64_t>> minimum_delay_ms_values =
|
||||
DecodeDeltas(proto.minimum_delay_ms_deltas(),
|
||||
ToUnsigned(proto.minimum_delay_ms()), number_of_deltas);
|
||||
RTC_PARSE_CHECK_OR_RETURN_EQ(minimum_delay_ms_values.size(),
|
||||
number_of_deltas);
|
||||
|
||||
// Populate events from decoded deltas
|
||||
for (size_t i = 0; i < number_of_deltas; ++i) {
|
||||
RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
|
||||
RTC_PARSE_CHECK_OR_RETURN(remote_ssrc_values[i].has_value());
|
||||
RTC_PARSE_CHECK_OR_RETURN_LE(remote_ssrc_values[i].value(),
|
||||
std::numeric_limits<uint32_t>::max());
|
||||
RTC_PARSE_CHECK_OR_RETURN(minimum_delay_ms_values[i].has_value());
|
||||
|
||||
int64_t timestamp_ms;
|
||||
RTC_PARSE_CHECK_OR_RETURN(
|
||||
ToSigned(timestamp_ms_values[i].value(), ×tamp_ms));
|
||||
|
||||
const uint32_t remote_ssrc =
|
||||
static_cast<uint32_t>(remote_ssrc_values[i].value());
|
||||
int minimum_delay_ms;
|
||||
RTC_PARSE_CHECK_OR_RETURN(
|
||||
ToSigned(minimum_delay_ms_values[i].value(), &minimum_delay_ms));
|
||||
neteq_set_minimum_delay_events_[remote_ssrc].emplace_back(
|
||||
Timestamp::Millis(timestamp_ms), remote_ssrc, minimum_delay_ms);
|
||||
}
|
||||
|
||||
return ParseStatus::Success();
|
||||
}
|
||||
|
||||
ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIncomingRtpPackets(
|
||||
const rtclog2::IncomingRtpPackets& proto) {
|
||||
return StoreRtpPackets(proto, &incoming_rtp_packets_map_);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
|
||||
|
@ -451,6 +452,11 @@ class ParsedRtcEventLog {
|
|||
return audio_playout_events_;
|
||||
}
|
||||
|
||||
const std::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>&
|
||||
neteq_set_minimum_delay_events() const {
|
||||
return neteq_set_minimum_delay_events_;
|
||||
}
|
||||
|
||||
const std::vector<LoggedAudioNetworkAdaptationEvent>&
|
||||
audio_network_adaptation_events() const {
|
||||
return audio_network_adaptation_events_;
|
||||
|
@ -763,6 +769,8 @@ class ParsedRtcEventLog {
|
|||
ParseStatus StoreIncomingRtcpPackets(
|
||||
const rtclog2::IncomingRtcpPackets& proto);
|
||||
ParseStatus StoreIncomingRtpPackets(const rtclog2::IncomingRtpPackets& proto);
|
||||
ParseStatus StoreNetEqSetMinimumDelay(
|
||||
const rtclog2::NetEqSetMinimumDelay& proto);
|
||||
ParseStatus StoreOutgoingRtcpPackets(
|
||||
const rtclog2::OutgoingRtcpPackets& proto);
|
||||
ParseStatus StoreOutgoingRtpPackets(const rtclog2::OutgoingRtpPackets& proto);
|
||||
|
@ -858,6 +866,8 @@ class ParsedRtcEventLog {
|
|||
|
||||
std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>
|
||||
audio_playout_events_;
|
||||
std::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>
|
||||
neteq_set_minimum_delay_events_;
|
||||
|
||||
std::vector<LoggedAudioNetworkAdaptationEvent>
|
||||
audio_network_adaptation_events_;
|
||||
|
|
|
@ -116,6 +116,12 @@ EventGenerator::NewAudioNetworkAdaptation() {
|
|||
return std::make_unique<RtcEventAudioNetworkAdaptation>(std::move(config));
|
||||
}
|
||||
|
||||
std::unique_ptr<RtcEventNetEqSetMinimumDelay>
|
||||
EventGenerator::NewNetEqSetMinimumDelay(uint32_t ssrc) {
|
||||
return std::make_unique<RtcEventNetEqSetMinimumDelay>(
|
||||
ssrc, prng_.Rand(std::numeric_limits<int>::max()));
|
||||
}
|
||||
|
||||
std::unique_ptr<RtcEventBweUpdateDelayBased>
|
||||
EventGenerator::NewBweUpdateDelayBased() {
|
||||
constexpr int32_t kMaxBweBps = 20000000;
|
||||
|
@ -1351,5 +1357,13 @@ void EventVerifier::VerifyLoggedVideoSendConfig(
|
|||
VerifyLoggedStreamConfig(original_event.config(), logged_event.config);
|
||||
}
|
||||
|
||||
void EventVerifier::VerifyLoggedNetEqSetMinimumDelay(
|
||||
const RtcEventNetEqSetMinimumDelay& original_event,
|
||||
const LoggedNetEqSetMinimumDelayEvent& logged_event) const {
|
||||
EXPECT_EQ(original_event.timestamp_ms(), logged_event.timestamp.ms());
|
||||
EXPECT_EQ(original_event.remote_ssrc(), logged_event.remote_ssrc);
|
||||
EXPECT_EQ(original_event.minimum_delay_ms(), logged_event.minimum_delay_ms);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -79,6 +79,8 @@ class EventGenerator {
|
|||
std::unique_ptr<RtcEventGenericPacketSent> NewGenericPacketSent();
|
||||
std::unique_ptr<RtcEventIceCandidatePair> NewIceCandidatePair();
|
||||
std::unique_ptr<RtcEventIceCandidatePairConfig> NewIceCandidatePairConfig();
|
||||
std::unique_ptr<RtcEventNetEqSetMinimumDelay> NewNetEqSetMinimumDelay(
|
||||
uint32_t ssrc);
|
||||
std::unique_ptr<RtcEventProbeClusterCreated> NewProbeClusterCreated();
|
||||
std::unique_ptr<RtcEventProbeResultFailure> NewProbeResultFailure();
|
||||
std::unique_ptr<RtcEventProbeResultSuccess> NewProbeResultSuccess();
|
||||
|
@ -317,6 +319,10 @@ class EventVerifier {
|
|||
const RtcEventVideoSendStreamConfig& original_event,
|
||||
const LoggedVideoSendConfig& logged_event) const;
|
||||
|
||||
void VerifyLoggedNetEqSetMinimumDelay(
|
||||
const RtcEventNetEqSetMinimumDelay& original_event,
|
||||
const LoggedNetEqSetMinimumDelayEvent& logged_event) const;
|
||||
|
||||
private:
|
||||
void VerifyReportBlock(const rtcp::ReportBlock& original_report_block,
|
||||
const rtcp::ReportBlock& logged_report_block);
|
||||
|
|
Loading…
Reference in a new issue