Prepare for new event log parser.

Minor clean up of BUILD file.
Add explicit events for begin and end of log.
Add a helper function to populate timestamps.
Add a GroupKey method that will be used for grouping events by for example SSRC in additon to event type.

Bug: webrtc:11933
Change-Id: Ie3c5f5a5582c89805a0273f4b27978f47ed0fb4f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/234260
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35725}
This commit is contained in:
Björn Terelius
2022-01-18 16:03:42 +01:00
committed by WebRTC LUCI CQ
parent 1d99f49cda
commit c15bced118
14 changed files with 347 additions and 75 deletions

View File

@ -27,7 +27,7 @@ class RtcEvent {
// of Type. This leaks the information of existing subclasses into the
// superclass, but the *actual* information - rtclog::StreamConfig, etc. -
// is kept separate.
enum class Type {
enum class Type : uint32_t {
AlrStateEvent,
RouteChangeEvent,
RemoteEstimateEvent,
@ -53,7 +53,9 @@ class RtcEvent {
GenericPacketSent,
GenericPacketReceived,
GenericAckReceived,
FrameDecoded
FrameDecoded,
BeginV3Log = 0x2501580,
EndV3Log = 0x2501581
};
RtcEvent();
@ -63,6 +65,13 @@ class RtcEvent {
virtual bool IsConfigEvent() const = 0;
// Events are grouped by Type before being encoded.
// Optionally, `GetGroupKey` can be overloaded to group the
// events by a secondary key (in addition to the event type.)
// This can, in some cases, improve compression efficiency
// e.g. by grouping events by SSRC.
virtual uint32_t GetGroupKey() const { return 0; }
int64_t timestamp_ms() const { return timestamp_us_ / 1000; }
int64_t timestamp_us() const { return timestamp_us_; }

View File

@ -29,7 +29,7 @@ class RtcEventLog {
// TODO(eladalon): Get rid of the legacy encoding and this enum once all
// clients have migrated to the new format.
enum class EncodingType { Legacy, NewFormat };
enum class EncodingType { Legacy, NewFormat, ProtoFree };
virtual ~RtcEventLog() = default;

View File

@ -18,6 +18,7 @@ if (is_android) {
group("logging") {
deps = [
":rtc_event_audio",
":rtc_event_begin_end",
":rtc_event_bwe",
":rtc_event_log_impl_encoder",
":rtc_event_pacing",
@ -48,6 +49,7 @@ rtc_library("rtc_event_field") {
":rtc_event_number_encodings",
"../api:array_view",
"../api/rtc_event_log",
"../api/units:timestamp",
"../rtc_base:bitstream_reader",
"../rtc_base:checks",
"../rtc_base:logging",
@ -78,7 +80,7 @@ rtc_library("rtc_event_pacing") {
]
deps = [
"../api:scoped_refptr",
":rtc_event_field",
"../api/rtc_event_log",
"../api/units:timestamp",
]
@ -99,7 +101,6 @@ rtc_library("rtc_event_audio") {
deps = [
":rtc_stream_config",
"../api:scoped_refptr",
"../api/rtc_event_log",
"../api/units:timestamp",
"../modules/audio_coding:audio_network_adaptor_config",
@ -108,6 +109,22 @@ rtc_library("rtc_event_audio") {
absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
rtc_library("rtc_event_begin_end") {
sources = [
"rtc_event_log/events/rtc_event_begin_log.cc",
"rtc_event_log/events/rtc_event_begin_log.h",
"rtc_event_log/events/rtc_event_end_log.cc",
"rtc_event_log/events/rtc_event_end_log.h",
]
deps = [
":rtc_event_field",
"../api:array_view",
"../api/rtc_event_log",
"../api/units:timestamp",
]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
}
rtc_library("rtc_event_bwe") {
sources = [
"rtc_event_log/events/rtc_event_bwe_update_delay_based.cc",
@ -127,7 +144,6 @@ rtc_library("rtc_event_bwe") {
deps = [
"../api:network_state_predictor_api",
"../api:scoped_refptr",
"../api/rtc_event_log",
"../api/units:data_rate",
"../api/units:timestamp",
@ -190,7 +206,6 @@ rtc_library("rtc_event_rtp_rtcp") {
deps = [
"../api:array_view",
"../api:scoped_refptr",
"../api/rtc_event_log",
"../modules/rtp_rtcp:rtp_rtcp_format",
"../rtc_base:checks",
@ -209,7 +224,6 @@ rtc_library("rtc_event_video") {
deps = [
":rtc_stream_config",
"../api:scoped_refptr",
"../api/rtc_event_log",
"../api/units:timestamp",
"../rtc_base:checks",
@ -275,6 +289,7 @@ rtc_library("rtc_event_log_impl_encoder") {
deps += [
":ice_log",
":rtc_event_audio",
":rtc_event_begin_end",
":rtc_event_bwe",
":rtc_event_frame_events",
":rtc_event_generic_packet_events",
@ -374,6 +389,7 @@ if (rtc_enable_protobuf) {
deps = [
":ice_log",
":rtc_event_audio",
":rtc_event_begin_end",
":rtc_event_bwe",
":rtc_event_frame_events",
":rtc_event_generic_packet_events",

View File

@ -363,6 +363,12 @@ std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
static_cast<const RtcEventVideoSendStreamConfig&>(event);
return EncodeVideoSendStreamConfig(rtc_event);
}
case RtcEvent::Type::BeginV3Log:
case RtcEvent::Type::EndV3Log:
// These special events are written as part of starting
// and stopping the log, and only as part of version 3 of the format.
RTC_DCHECK_NOTREACHED();
break;
case RtcEvent::Type::RouteChangeEvent:
case RtcEvent::Type::RemoteEstimateEvent:
case RtcEvent::Type::GenericPacketReceived:

View File

@ -880,6 +880,12 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
frames_decoded[rtc_event->ssrc()].emplace_back(rtc_event);
break;
}
case RtcEvent::Type::BeginV3Log:
case RtcEvent::Type::EndV3Log:
// These special events are written as part of starting
// and stopping the log, and only as part of version 3 of the format.
RTC_DCHECK_NOTREACHED();
break;
}
}

View File

@ -61,6 +61,10 @@ class RtcEventLogEncoderTest
case RtcEventLog::EncodingType::NewFormat:
encoder_ = std::make_unique<RtcEventLogEncoderNewFormat>();
break;
case RtcEventLog::EncodingType::ProtoFree:
// TODO(terelius): Enable test once the format has been wired up.
RTC_CHECK_NOTREACHED();
break;
}
encoded_ =
encoder_->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis());
@ -1285,6 +1289,10 @@ class RtcEventLogEncoderSimpleTest
case RtcEventLog::EncodingType::NewFormat:
encoder_ = std::make_unique<RtcEventLogEncoderNewFormat>();
break;
case RtcEventLog::EncodingType::ProtoFree:
// TODO(terelius): Enable test once the format has been wired up.
RTC_CHECK_NOTREACHED();
break;
}
encoded_ =
encoder_->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis());

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2021 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_begin_log.h"
#include "absl/strings/string_view.h"
namespace webrtc {
constexpr RtcEvent::Type RtcEventBeginLog::kType;
constexpr EventParameters RtcEventBeginLog::event_params_;
constexpr FieldParameters RtcEventBeginLog::utc_start_time_params_;
RtcEventBeginLog::RtcEventBeginLog(Timestamp timestamp,
Timestamp utc_start_time)
: RtcEvent(timestamp.us()), utc_start_time_ms_(utc_start_time.ms()) {}
RtcEventBeginLog::RtcEventBeginLog(const RtcEventBeginLog& other)
: RtcEvent(other.timestamp_us_) {}
RtcEventBeginLog::~RtcEventBeginLog() = default;
std::string RtcEventBeginLog::Encode(rtc::ArrayView<const RtcEvent*> batch) {
EventEncoder encoder(event_params_, batch);
encoder.EncodeField(
utc_start_time_params_,
ExtractRtcEventMember(batch, &RtcEventBeginLog::utc_start_time_ms_));
return encoder.AsString();
}
RtcEventLogParseStatus RtcEventBeginLog::Parse(
absl::string_view encoded_bytes,
bool batched,
std::vector<LoggedStartEvent>& output) {
EventParser parser;
auto status = parser.Initialize(encoded_bytes, batched);
if (!status.ok())
return status;
rtc::ArrayView<LoggedStartEvent> output_batch =
ExtendLoggedBatch(output, parser.NumEventsInBatch());
constexpr FieldParameters timestamp_params{
"timestamp_ms", FieldParameters::kTimestampField, FieldType::kVarInt, 64};
RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
parser.ParseNumericField(timestamp_params);
if (!result.ok())
return result.status();
PopulateRtcEventTimestamp(result.value(), &LoggedStartEvent::timestamp,
output_batch);
result = parser.ParseNumericField(utc_start_time_params_);
if (!result.ok())
return result.status();
PopulateRtcEventTimestamp(result.value(), &LoggedStartEvent::utc_start_time,
output_batch);
return RtcEventLogParseStatus::Success();
}
} // namespace webrtc

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021 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_BEGIN_LOG_H_
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BEGIN_LOG_H_
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/rtc_event_log/rtc_event.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
namespace webrtc {
struct LoggedStartEvent {
LoggedStartEvent() = default;
explicit LoggedStartEvent(Timestamp timestamp)
: LoggedStartEvent(timestamp, timestamp) {}
LoggedStartEvent(Timestamp timestamp, Timestamp utc_start_time)
: timestamp(timestamp), utc_start_time(utc_start_time) {}
int64_t log_time_us() const { return timestamp.us(); }
int64_t log_time_ms() const { return timestamp.ms(); }
Timestamp utc_time() const { return utc_start_time; }
Timestamp timestamp = Timestamp::PlusInfinity();
Timestamp utc_start_time = Timestamp::PlusInfinity();
};
class RtcEventBeginLog final : public RtcEvent {
public:
static constexpr Type kType = Type::BeginV3Log;
RtcEventBeginLog(Timestamp timestamp, Timestamp utc_start_time);
~RtcEventBeginLog() override;
Type GetType() const override { return kType; }
bool IsConfigEvent() const override { return false; }
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch);
static RtcEventLogParseStatus Parse(absl::string_view encoded_bytes,
bool batched,
std::vector<LoggedStartEvent>& output);
private:
RtcEventBeginLog(const RtcEventBeginLog& other);
int64_t utc_start_time_ms_;
static constexpr EventParameters event_params_{"BeginLog",
RtcEventBeginLog::kType};
static constexpr FieldParameters utc_start_time_params_{
"utc_start_time_ms", /*id=*/1, FieldType::kVarInt, /*width=*/64};
};
} // namespace webrtc
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BEGIN_LOG_H_

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 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_end_log.h"
#include "absl/strings/string_view.h"
namespace webrtc {
constexpr RtcEvent::Type RtcEventEndLog::kType;
constexpr EventParameters RtcEventEndLog::event_params_;
RtcEventEndLog::RtcEventEndLog(Timestamp timestamp)
: RtcEvent(timestamp.us()) {}
RtcEventEndLog::RtcEventEndLog(const RtcEventEndLog& other)
: RtcEvent(other.timestamp_us_) {}
RtcEventEndLog::~RtcEventEndLog() = default;
std::string RtcEventEndLog::Encode(rtc::ArrayView<const RtcEvent*> batch) {
EventEncoder encoder(event_params_, batch);
return encoder.AsString();
}
RtcEventLogParseStatus RtcEventEndLog::Parse(
absl::string_view encoded_bytes,
bool batched,
std::vector<LoggedStopEvent>& output) {
EventParser parser;
auto status = parser.Initialize(encoded_bytes, batched);
if (!status.ok())
return status;
rtc::ArrayView<LoggedStopEvent> output_batch =
ExtendLoggedBatch(output, parser.NumEventsInBatch());
constexpr FieldParameters timestamp_params{
"timestamp_ms", FieldParameters::kTimestampField, FieldType::kVarInt, 64};
RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
parser.ParseNumericField(timestamp_params);
if (!result.ok())
return result.status();
PopulateRtcEventTimestamp(result.value(), &LoggedStopEvent::timestamp,
output_batch);
return RtcEventLogParseStatus::Success();
}
} // namespace webrtc

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 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_END_LOG_H_
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_END_LOG_H_
#include <memory>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/rtc_event_log/rtc_event.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
namespace webrtc {
struct LoggedStopEvent {
LoggedStopEvent() = default;
explicit LoggedStopEvent(Timestamp timestamp) : timestamp(timestamp) {}
int64_t log_time_us() const { return timestamp.us(); }
int64_t log_time_ms() const { return timestamp.ms(); }
Timestamp timestamp = Timestamp::PlusInfinity();
};
class RtcEventEndLog final : public RtcEvent {
public:
static constexpr Type kType = Type::EndV3Log;
explicit RtcEventEndLog(Timestamp timestamp);
~RtcEventEndLog() override;
Type GetType() const override { return kType; }
bool IsConfigEvent() const override { return false; }
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch);
static RtcEventLogParseStatus Parse(absl::string_view encoded_bytes,
bool batched,
std::vector<LoggedStopEvent>& output);
private:
RtcEventEndLog(const RtcEventEndLog& other);
static constexpr EventParameters event_params_{"EndLog",
RtcEventEndLog::kType};
};
} // namespace webrtc
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_END_LOG_H_

View File

@ -36,6 +36,7 @@ class RtcEventLogParseStatus {
}
bool ok() const { return error_.empty(); }
ABSL_DEPRECATED("Use ok() instead") operator bool() const { return ok(); }
std::string message() const { return error_; }
@ -50,15 +51,17 @@ class RtcEventLogParseStatus {
template <typename T>
class RtcEventLogParseStatusOr {
public:
explicit RtcEventLogParseStatusOr(RtcEventLogParseStatus status)
RtcEventLogParseStatusOr(RtcEventLogParseStatus status) // NOLINT
: status_(status), value_() {}
explicit RtcEventLogParseStatusOr(const T& value)
RtcEventLogParseStatusOr(const T& value) // NOLINT
: status_(), value_(value) {}
bool ok() const { return status_.ok(); }
std::string message() const { return status_.message(); }
RtcEventLogParseStatus status() const { return status_; }
const T& value() const {
RTC_DCHECK(ok());
return value_;

View File

@ -17,6 +17,7 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/rtc_event_log/rtc_event.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
#include "rtc_base/logging.h"
@ -181,6 +182,29 @@ void PopulateRtcEventMember(const rtc::ArrayView<absl::string_view> values,
}
}
template <typename E>
void PopulateRtcEventTimestamp(const rtc::ArrayView<uint64_t>& values,
Timestamp E::*timestamp,
rtc::ArrayView<E> output) {
size_t batch_size = values.size();
RTC_CHECK_EQ(batch_size, output.size());
for (size_t i = 0; i < batch_size; ++i) {
output[i].*timestamp =
Timestamp::Millis(DecodeFromUnsignedToType<int64_t>(values[i]));
}
}
template <typename E>
rtc::ArrayView<E> ExtendLoggedBatch(std::vector<E>& output,
size_t new_elements) {
size_t old_size = output.size();
output.insert(output.end(), old_size + new_elements, E());
rtc::ArrayView<E> output_batch = output;
output_batch.subview(old_size);
RTC_DCHECK_EQ(output_batch.size(), new_elements);
return output_batch;
}
} // namespace webrtc
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_

View File

@ -239,31 +239,6 @@ struct LoggedRtcpPacketBye {
rtcp::Bye bye;
};
struct LoggedStartEvent {
explicit LoggedStartEvent(Timestamp timestamp)
: LoggedStartEvent(timestamp, timestamp) {}
LoggedStartEvent(Timestamp timestamp, Timestamp utc_start_time)
: timestamp(timestamp), utc_start_time(utc_start_time) {}
int64_t log_time_us() const { return timestamp.us(); }
int64_t log_time_ms() const { return timestamp.ms(); }
Timestamp utc_time() const { return utc_start_time; }
Timestamp timestamp;
Timestamp utc_start_time;
};
struct LoggedStopEvent {
explicit LoggedStopEvent(Timestamp timestamp) : timestamp(timestamp) {}
int64_t log_time_us() const { return timestamp.us(); }
int64_t log_time_ms() const { return timestamp.ms(); }
Timestamp timestamp;
};
struct InferredRouteChangeEvent {
int64_t log_time_ms() const { return log_time.ms(); }
int64_t log_time_us() const { return log_time.us(); }

View File

@ -15,7 +15,6 @@
#include <map>
#include <set>
#include <string>
#include <utility> // pair
#include <vector>
#include "absl/base/attributes.h"
@ -27,10 +26,12 @@
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_begin_log.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
#include "logging/rtc_event_log/events/rtc_event_end_log.h"
#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
@ -240,48 +241,11 @@ class ParsedRtcEventLog {
kDontParse,
kAttemptWebrtcDefaultConfig
};
class ParseStatus {
public:
static ParseStatus Success() { return ParseStatus(); }
static ParseStatus Error(std::string error, std::string file, int line) {
return ParseStatus(error, file, line);
}
bool ok() const { return error_.empty() && file_.empty() && line_ == 0; }
std::string message() const {
return error_ + " failed at " + file_ + " line " + std::to_string(line_);
}
ABSL_DEPRECATED("Use ok() instead") operator bool() const { return ok(); }
private:
ParseStatus() : error_(), file_(), line_(0) {}
ParseStatus(std::string error, std::string file, int line)
: error_(error), file_(file), line_(line) {}
std::string error_;
std::string file_;
int line_;
};
using ParseStatus = RtcEventLogParseStatus;
template <typename T>
class ParseStatusOr {
public:
ParseStatusOr(const ParseStatus& error) // NOLINT
: status_(error), value_() {}
ParseStatusOr(const T& value) // NOLINT
: status_(ParseStatus::Success()), value_(value) {}
bool ok() const { return status_.ok(); }
const T& value() const& {
RTC_DCHECK(status_.ok());
return value_;
}
std::string message() const { return status_.message(); }
const ParseStatus& status() const { return status_; }
private:
ParseStatus status_;
T value_;
};
using ParseStatusOr = RtcEventLogParseStatusOr<T>;
struct LoggedRtpStreamIncoming {
LoggedRtpStreamIncoming();