Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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/dependency_descriptor_encoder_decoder.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "logging/rtc_event_log/encoder/delta_encoding.h"
|
||||
#include "logging/rtc_event_log/encoder/optional_blob_encoding.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log2_proto_include.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
absl::optional<rtclog2::DependencyDescriptorsWireInfo>
|
||||
RtcEventLogDependencyDescriptorEncoderDecoder::Encode(
|
||||
const std::vector<rtc::ArrayView<const uint8_t>>& raw_dd_data) {
|
||||
if (raw_dd_data.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
for (const auto& dd : raw_dd_data) {
|
||||
if (!dd.empty() && dd.size() < 3) {
|
||||
RTC_LOG(LS_WARNING) << "DependencyDescriptor size not valid.";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
rtclog2::DependencyDescriptorsWireInfo res;
|
||||
const rtc::ArrayView<const uint8_t>& base_dd = raw_dd_data[0];
|
||||
auto delta_dds =
|
||||
rtc::MakeArrayView(raw_dd_data.data(), raw_dd_data.size()).subview(1);
|
||||
|
||||
// Start and end bit.
|
||||
{
|
||||
absl::optional<uint32_t> start_end_bit;
|
||||
if (!base_dd.empty()) {
|
||||
start_end_bit = (base_dd[0] >> 6);
|
||||
res.set_start_end_bit(*start_end_bit);
|
||||
}
|
||||
if (!delta_dds.empty()) {
|
||||
std::vector<absl::optional<uint64_t>> values(delta_dds.size());
|
||||
for (size_t i = 0; i < delta_dds.size(); ++i) {
|
||||
if (!delta_dds[i].empty()) {
|
||||
values[i] = delta_dds[i][0] >> 6;
|
||||
}
|
||||
}
|
||||
std::string encoded_deltas = EncodeDeltas(start_end_bit, values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
res.set_start_end_bit_deltas(encoded_deltas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Template IDs.
|
||||
{
|
||||
absl::optional<uint32_t> template_id;
|
||||
if (!base_dd.empty()) {
|
||||
template_id = (base_dd[0] & 0b0011'1111);
|
||||
res.set_template_id(*template_id);
|
||||
}
|
||||
|
||||
if (!delta_dds.empty()) {
|
||||
std::vector<absl::optional<uint64_t>> values(delta_dds.size());
|
||||
for (size_t i = 0; i < delta_dds.size(); ++i) {
|
||||
if (!delta_dds[i].empty()) {
|
||||
values[i] = delta_dds[i][0] & 0b0011'1111;
|
||||
}
|
||||
}
|
||||
std::string encoded_deltas = EncodeDeltas(template_id, values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
res.set_template_id_deltas(encoded_deltas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Frame IDs.
|
||||
{
|
||||
absl::optional<uint32_t> frame_id;
|
||||
if (!base_dd.empty()) {
|
||||
frame_id = (uint16_t{base_dd[1]} << 8) + base_dd[2];
|
||||
res.set_frame_id(*frame_id);
|
||||
}
|
||||
|
||||
if (!delta_dds.empty()) {
|
||||
std::vector<absl::optional<uint64_t>> values(delta_dds.size());
|
||||
for (size_t i = 0; i < delta_dds.size(); ++i) {
|
||||
if (!delta_dds[i].empty()) {
|
||||
values[i] = (uint16_t{delta_dds[i][1]} << 8) + delta_dds[i][2];
|
||||
}
|
||||
}
|
||||
std::string encoded_deltas = EncodeDeltas(frame_id, values);
|
||||
if (!encoded_deltas.empty()) {
|
||||
res.set_frame_id_deltas(encoded_deltas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extended info
|
||||
{
|
||||
std::vector<absl::optional<std::string>> values(raw_dd_data.size());
|
||||
for (size_t i = 0; i < raw_dd_data.size(); ++i) {
|
||||
if (raw_dd_data[i].size() > 3) {
|
||||
auto extended_info = raw_dd_data[i].subview(3);
|
||||
values[i] = {reinterpret_cast<const char*>(extended_info.data()),
|
||||
extended_info.size()};
|
||||
}
|
||||
}
|
||||
|
||||
std::string encoded_blobs = EncodeOptionalBlobs(values);
|
||||
if (!encoded_blobs.empty()) {
|
||||
res.set_extended_infos(encoded_blobs);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// static
|
||||
RtcEventLogParseStatusOr<std::vector<std::vector<uint8_t>>>
|
||||
RtcEventLogDependencyDescriptorEncoderDecoder::Decode(
|
||||
const rtclog2::DependencyDescriptorsWireInfo& dd_wire_info,
|
||||
size_t num_packets) {
|
||||
if (num_packets == 0) {
|
||||
return {std::vector<std::vector<uint8_t>>()};
|
||||
}
|
||||
|
||||
std::vector<std::vector<uint8_t>> res(num_packets);
|
||||
|
||||
absl::optional<uint64_t> start_end_bit_base;
|
||||
if (dd_wire_info.has_start_end_bit()) {
|
||||
start_end_bit_base = dd_wire_info.start_end_bit();
|
||||
}
|
||||
absl::optional<uint64_t> template_id_base;
|
||||
if (dd_wire_info.has_template_id()) {
|
||||
template_id_base = dd_wire_info.template_id();
|
||||
}
|
||||
absl::optional<uint64_t> frame_id_base;
|
||||
if (dd_wire_info.has_frame_id()) {
|
||||
frame_id_base = dd_wire_info.frame_id();
|
||||
}
|
||||
|
||||
std::vector<absl::optional<uint64_t>> start_end_bit_deltas;
|
||||
if (dd_wire_info.has_start_end_bit_deltas()) {
|
||||
start_end_bit_deltas = DecodeDeltas(dd_wire_info.start_end_bit_deltas(),
|
||||
start_end_bit_base, num_packets - 1);
|
||||
RTC_DCHECK(start_end_bit_deltas.empty() ||
|
||||
start_end_bit_deltas.size() == (num_packets - 1));
|
||||
}
|
||||
std::vector<absl::optional<uint64_t>> template_id_deltas;
|
||||
if (dd_wire_info.has_template_id_deltas()) {
|
||||
template_id_deltas = DecodeDeltas(dd_wire_info.template_id_deltas(),
|
||||
template_id_base, num_packets - 1);
|
||||
RTC_DCHECK(template_id_deltas.empty() ||
|
||||
template_id_deltas.size() == (num_packets - 1));
|
||||
}
|
||||
std::vector<absl::optional<uint64_t>> frame_id_deltas;
|
||||
if (dd_wire_info.has_frame_id_deltas()) {
|
||||
frame_id_deltas = DecodeDeltas(dd_wire_info.frame_id_deltas(),
|
||||
frame_id_base, num_packets - 1);
|
||||
RTC_DCHECK(frame_id_deltas.empty() ||
|
||||
frame_id_deltas.size() == (num_packets - 1));
|
||||
}
|
||||
std::vector<absl::optional<std::string>> extended_infos;
|
||||
if (dd_wire_info.has_extended_infos()) {
|
||||
extended_infos =
|
||||
DecodeOptionalBlobs(dd_wire_info.extended_infos(), num_packets);
|
||||
}
|
||||
|
||||
auto recreate_raw_dd = [&](int i, const absl::optional<uint64_t>& be,
|
||||
const absl::optional<uint64_t>& tid,
|
||||
const absl::optional<uint64_t>& fid) {
|
||||
absl::string_view ext;
|
||||
if (!extended_infos.empty() && extended_infos[i].has_value()) {
|
||||
ext = *extended_infos[i];
|
||||
}
|
||||
if (be.has_value() && tid.has_value() && fid.has_value()) {
|
||||
res[i].reserve(3 + ext.size());
|
||||
res[i].push_back((*be << 6) | *tid);
|
||||
res[i].push_back(*fid >> 8);
|
||||
res[i].push_back(*fid);
|
||||
if (!ext.empty()) {
|
||||
res[i].insert(res[i].end(), ext.begin(), ext.end());
|
||||
}
|
||||
} else if (be.has_value() || tid.has_value() || fid.has_value()) {
|
||||
RTC_PARSE_RETURN_ERROR("Not all required fields present.");
|
||||
} else if (!ext.empty()) {
|
||||
RTC_PARSE_RETURN_ERROR(
|
||||
"Extended info present without required fields present.");
|
||||
}
|
||||
|
||||
return RtcEventLogParseStatus::Success();
|
||||
};
|
||||
|
||||
RTC_RETURN_IF_ERROR(
|
||||
recreate_raw_dd(0, start_end_bit_base, template_id_base, frame_id_base));
|
||||
|
||||
for (size_t i = 1; i < num_packets; ++i) {
|
||||
RTC_RETURN_IF_ERROR(recreate_raw_dd(
|
||||
i,
|
||||
start_end_bit_deltas.empty() ? start_end_bit_base
|
||||
: start_end_bit_deltas[i - 1],
|
||||
template_id_deltas.empty() ? template_id_base
|
||||
: template_id_deltas[i - 1],
|
||||
frame_id_deltas.empty() ? frame_id_base : frame_id_deltas[i - 1]));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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_DEPENDENCY_DESCRIPTOR_ENCODER_DECODER_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_DEPENDENCY_DESCRIPTOR_ENCODER_DECODER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log2_proto_include.h"
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtcEventLogDependencyDescriptorEncoderDecoder {
|
||||
public:
|
||||
static absl::optional<rtclog2::DependencyDescriptorsWireInfo> Encode(
|
||||
const std::vector<rtc::ArrayView<const uint8_t>>& raw_dd_data);
|
||||
static RtcEventLogParseStatusOr<std::vector<std::vector<uint8_t>>> Decode(
|
||||
const rtclog2::DependencyDescriptorsWireInfo& dd_wire_info,
|
||||
size_t num_packets);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_DEPENDENCY_DESCRIPTOR_ENCODER_DECODER_H_
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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/encoder/bit_writer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
size_t BitsToBytes(size_t bits) {
|
||||
return (bits / 8) + (bits % 8 > 0 ? 1 : 0);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void BitWriter::WriteBits(uint64_t val, size_t bit_count) {
|
||||
RTC_DCHECK(valid_);
|
||||
const bool success = bit_writer_.WriteBits(val, bit_count);
|
||||
RTC_DCHECK(success);
|
||||
written_bits_ += bit_count;
|
||||
}
|
||||
|
||||
void BitWriter::WriteBits(absl::string_view input) {
|
||||
RTC_DCHECK(valid_);
|
||||
for (char c : input) {
|
||||
WriteBits(static_cast<unsigned char>(c), CHAR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns everything that was written so far.
|
||||
// Nothing more may be written after this is called.
|
||||
std::string BitWriter::GetString() {
|
||||
RTC_DCHECK(valid_);
|
||||
valid_ = false;
|
||||
|
||||
buffer_.resize(BitsToBytes(written_bits_));
|
||||
written_bits_ = 0;
|
||||
|
||||
std::string result;
|
||||
std::swap(buffer_, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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_ENCODER_BIT_WRITER_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_BIT_WRITER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "rtc_base/bit_buffer.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Wrap BitBufferWriter and extend its functionality by (1) keeping track of
|
||||
// the number of bits written and (2) owning its buffer.
|
||||
class BitWriter final {
|
||||
public:
|
||||
explicit BitWriter(size_t byte_count)
|
||||
: buffer_(byte_count, '\0'),
|
||||
bit_writer_(reinterpret_cast<uint8_t*>(&buffer_[0]), buffer_.size()),
|
||||
written_bits_(0),
|
||||
valid_(true) {
|
||||
RTC_DCHECK_GT(byte_count, 0);
|
||||
}
|
||||
|
||||
BitWriter(const BitWriter&) = delete;
|
||||
BitWriter& operator=(const BitWriter&) = delete;
|
||||
|
||||
void WriteBits(uint64_t val, size_t bit_count);
|
||||
|
||||
void WriteBits(absl::string_view input);
|
||||
|
||||
// Returns everything that was written so far.
|
||||
// Nothing more may be written after this is called.
|
||||
std::string GetString();
|
||||
|
||||
private:
|
||||
std::string buffer_;
|
||||
rtc::BitBufferWriter bit_writer_;
|
||||
// Note: Counting bits instead of bytes wraps around earlier than it has to,
|
||||
// which means the maximum length is lower than it could be. We don't expect
|
||||
// to go anywhere near the limit, though, so this is good enough.
|
||||
size_t written_bits_;
|
||||
bool valid_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_BIT_WRITER_H_
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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/encoder/blob_encoding.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "logging/rtc_event_log/encoder/var_int.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string EncodeBlobs(const std::vector<std::string>& blobs) {
|
||||
RTC_DCHECK(!blobs.empty());
|
||||
|
||||
size_t result_length_bound = kMaxVarIntLengthBytes * blobs.size();
|
||||
for (const auto& blob : blobs) {
|
||||
// Providing an input so long that it would cause a wrap-around is an error.
|
||||
RTC_DCHECK_GE(result_length_bound + blob.length(), result_length_bound);
|
||||
result_length_bound += blob.length();
|
||||
}
|
||||
|
||||
std::string result;
|
||||
result.reserve(result_length_bound);
|
||||
|
||||
// First, encode all of the lengths.
|
||||
for (absl::string_view blob : blobs) {
|
||||
result += EncodeVarInt(blob.length());
|
||||
}
|
||||
|
||||
// Second, encode the actual blobs.
|
||||
for (absl::string_view blob : blobs) {
|
||||
result.append(blob.data(), blob.length());
|
||||
}
|
||||
|
||||
RTC_DCHECK_LE(result.size(), result_length_bound);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<absl::string_view> DecodeBlobs(absl::string_view encoded_blobs,
|
||||
size_t num_of_blobs) {
|
||||
if (encoded_blobs.empty()) {
|
||||
RTC_LOG(LS_WARNING) << "Corrupt input; empty input.";
|
||||
return std::vector<absl::string_view>();
|
||||
}
|
||||
|
||||
if (num_of_blobs == 0u) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "Corrupt input; number of blobs must be greater than 0.";
|
||||
return std::vector<absl::string_view>();
|
||||
}
|
||||
|
||||
// Read the lengths of all blobs.
|
||||
std::vector<uint64_t> lengths(num_of_blobs);
|
||||
for (size_t i = 0; i < num_of_blobs; ++i) {
|
||||
bool success = false;
|
||||
std::tie(success, encoded_blobs) = DecodeVarInt(encoded_blobs, &lengths[i]);
|
||||
if (!success) {
|
||||
RTC_LOG(LS_WARNING) << "Corrupt input; varint decoding failed.";
|
||||
return std::vector<absl::string_view>();
|
||||
}
|
||||
}
|
||||
|
||||
// Read the blobs themselves.
|
||||
std::vector<absl::string_view> blobs(num_of_blobs);
|
||||
for (size_t i = 0; i < num_of_blobs; ++i) {
|
||||
if (lengths[i] > encoded_blobs.length()) {
|
||||
RTC_LOG(LS_WARNING) << "Corrupt input; blob sizes exceed input size.";
|
||||
return std::vector<absl::string_view>();
|
||||
}
|
||||
|
||||
blobs[i] = encoded_blobs.substr(0, lengths[i]);
|
||||
encoded_blobs = encoded_blobs.substr(lengths[i]);
|
||||
}
|
||||
|
||||
if (!encoded_blobs.empty()) {
|
||||
RTC_LOG(LS_WARNING) << "Corrupt input; unrecognized trailer.";
|
||||
return std::vector<absl::string_view>();
|
||||
}
|
||||
|
||||
return blobs;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_ENCODER_BLOB_ENCODING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_BLOB_ENCODING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Encode/decode a sequence of strings, whose length is not known to be
|
||||
// discernable from the blob itself (i.e. without being transmitted OOB),
|
||||
// in a way that would allow us to separate them again on the decoding side.
|
||||
// The number of blobs is assumed to be transmitted OOB. For example, if
|
||||
// multiple sequences of different blobs are sent, but all sequences contain
|
||||
// the same number of blobs, it is beneficial to not encode the number of blobs.
|
||||
//
|
||||
// EncodeBlobs() must be given a non-empty vector. The blobs themselves may
|
||||
// be equal to "", though.
|
||||
// EncodeBlobs() may not fail.
|
||||
// EncodeBlobs() never returns the empty string.
|
||||
//
|
||||
// Calling DecodeBlobs() on an empty string, or with `num_of_blobs` set to 0,
|
||||
// is an error.
|
||||
// DecodeBlobs() returns an empty vector if it fails, e.g. due to a mismatch
|
||||
// between `num_of_blobs` and `encoded_blobs`, which can happen if
|
||||
// `encoded_blobs` is corrupted.
|
||||
// When successful, DecodeBlobs() returns a vector of string_view objects,
|
||||
// which refer to the original input (`encoded_blobs`), and therefore may
|
||||
// not outlive it.
|
||||
//
|
||||
// Note that the returned std::string might have been reserved for significantly
|
||||
// more memory than it ends up using. If the caller to EncodeBlobs() intends
|
||||
// to store the result long-term, they should consider shrink_to_fit()-ing it.
|
||||
std::string EncodeBlobs(const std::vector<std::string>& blobs);
|
||||
std::vector<absl::string_view> DecodeBlobs(absl::string_view encoded_blobs,
|
||||
size_t num_of_blobs);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_BLOB_ENCODING_H_
|
||||
|
|
@ -0,0 +1,839 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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/encoder/delta_encoding.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "logging/rtc_event_log/encoder/bit_writer.h"
|
||||
#include "logging/rtc_event_log/encoder/var_int.h"
|
||||
#include "rtc_base/bit_buffer.h"
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
// TODO(eladalon): Only build the decoder in tools and unit tests.
|
||||
|
||||
bool g_force_unsigned_for_testing = false;
|
||||
bool g_force_signed_for_testing = false;
|
||||
|
||||
size_t BitsToBytes(size_t bits) {
|
||||
return (bits / 8) + (bits % 8 > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
// TODO(eladalon): Replace by something more efficient.
|
||||
uint64_t UnsignedBitWidth(uint64_t input, bool zero_val_as_zero_width = false) {
|
||||
if (zero_val_as_zero_width && input == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t width = 0;
|
||||
do { // input == 0 -> width == 1
|
||||
width += 1;
|
||||
input >>= 1;
|
||||
} while (input != 0);
|
||||
return width;
|
||||
}
|
||||
|
||||
uint64_t SignedBitWidth(uint64_t max_pos_magnitude,
|
||||
uint64_t max_neg_magnitude) {
|
||||
const uint64_t bitwidth_pos = UnsignedBitWidth(max_pos_magnitude, true);
|
||||
const uint64_t bitwidth_neg =
|
||||
(max_neg_magnitude > 0) ? UnsignedBitWidth(max_neg_magnitude - 1, true)
|
||||
: 0;
|
||||
return 1 + std::max(bitwidth_pos, bitwidth_neg);
|
||||
}
|
||||
|
||||
// Return the maximum integer of a given bit width.
|
||||
// Examples:
|
||||
// MaxUnsignedValueOfBitWidth(1) = 0x01
|
||||
// MaxUnsignedValueOfBitWidth(6) = 0x3f
|
||||
// MaxUnsignedValueOfBitWidth(8) = 0xff
|
||||
// MaxUnsignedValueOfBitWidth(32) = 0xffffffff
|
||||
uint64_t MaxUnsignedValueOfBitWidth(uint64_t bit_width) {
|
||||
RTC_DCHECK_GE(bit_width, 1);
|
||||
RTC_DCHECK_LE(bit_width, 64);
|
||||
return (bit_width == 64) ? std::numeric_limits<uint64_t>::max()
|
||||
: ((static_cast<uint64_t>(1) << bit_width) - 1);
|
||||
}
|
||||
|
||||
// Computes the delta between `previous` and `current`, under the assumption
|
||||
// that wrap-around occurs after `width` is exceeded.
|
||||
uint64_t UnsignedDelta(uint64_t previous, uint64_t current, uint64_t bit_mask) {
|
||||
return (current - previous) & bit_mask;
|
||||
}
|
||||
|
||||
// Determines the encoding type (e.g. fixed-size encoding).
|
||||
// Given an encoding type, may also distinguish between some variants of it
|
||||
// (e.g. which fields of the fixed-size encoding are explicitly mentioned by
|
||||
// the header, and which are implicitly assumed to hold certain default values).
|
||||
enum class EncodingType {
|
||||
kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt = 0,
|
||||
kFixedSizeSignedDeltasEarlyWrapAndOptSupported = 1,
|
||||
kReserved1 = 2,
|
||||
kReserved2 = 3,
|
||||
kNumberOfEncodingTypes // Keep last
|
||||
};
|
||||
|
||||
// The width of each field in the encoding header. Note that this is the
|
||||
// width in case the field exists; not all fields occur in all encoding types.
|
||||
constexpr size_t kBitsInHeaderForEncodingType = 2;
|
||||
constexpr size_t kBitsInHeaderForDeltaWidthBits = 6;
|
||||
constexpr size_t kBitsInHeaderForSignedDeltas = 1;
|
||||
constexpr size_t kBitsInHeaderForValuesOptional = 1;
|
||||
constexpr size_t kBitsInHeaderForValueWidthBits = 6;
|
||||
|
||||
static_assert(static_cast<size_t>(EncodingType::kNumberOfEncodingTypes) <=
|
||||
1 << kBitsInHeaderForEncodingType,
|
||||
"Not all encoding types fit.");
|
||||
|
||||
// Default values for when the encoding header does not specify explicitly.
|
||||
constexpr bool kDefaultSignedDeltas = false;
|
||||
constexpr bool kDefaultValuesOptional = false;
|
||||
constexpr uint64_t kDefaultValueWidthBits = 64;
|
||||
|
||||
// Parameters for fixed-size delta-encoding/decoding.
|
||||
// These are tailored for the sequence which will be encoded (e.g. widths).
|
||||
class FixedLengthEncodingParameters final {
|
||||
public:
|
||||
static bool ValidParameters(uint64_t delta_width_bits,
|
||||
bool signed_deltas,
|
||||
bool values_optional,
|
||||
uint64_t value_width_bits) {
|
||||
return (1 <= delta_width_bits && delta_width_bits <= 64 &&
|
||||
1 <= value_width_bits && value_width_bits <= 64 &&
|
||||
delta_width_bits <= value_width_bits);
|
||||
}
|
||||
|
||||
FixedLengthEncodingParameters(uint64_t delta_width_bits,
|
||||
bool signed_deltas,
|
||||
bool values_optional,
|
||||
uint64_t value_width_bits)
|
||||
: delta_width_bits_(delta_width_bits),
|
||||
signed_deltas_(signed_deltas),
|
||||
values_optional_(values_optional),
|
||||
value_width_bits_(value_width_bits),
|
||||
delta_mask_(MaxUnsignedValueOfBitWidth(delta_width_bits_)),
|
||||
value_mask_(MaxUnsignedValueOfBitWidth(value_width_bits_)) {
|
||||
RTC_DCHECK(ValidParameters(delta_width_bits, signed_deltas, values_optional,
|
||||
value_width_bits));
|
||||
}
|
||||
|
||||
// Number of bits necessary to hold the widest(*) of the deltas between the
|
||||
// values in the sequence.
|
||||
// (*) - Widest might not be the largest, if signed deltas are used.
|
||||
uint64_t delta_width_bits() const { return delta_width_bits_; }
|
||||
|
||||
// Whether deltas are signed.
|
||||
bool signed_deltas() const { return signed_deltas_; }
|
||||
|
||||
// Whether the values of the sequence are optional. That is, it may be
|
||||
// that some of them do not have a value (not even a sentinel value indicating
|
||||
// invalidity).
|
||||
bool values_optional() const { return values_optional_; }
|
||||
|
||||
// Number of bits necessary to hold the largest value in the sequence.
|
||||
uint64_t value_width_bits() const { return value_width_bits_; }
|
||||
|
||||
// Masks where only the bits relevant to the deltas/values are turned on.
|
||||
uint64_t delta_mask() const { return delta_mask_; }
|
||||
uint64_t value_mask() const { return value_mask_; }
|
||||
|
||||
void SetSignedDeltas(bool signed_deltas) { signed_deltas_ = signed_deltas; }
|
||||
void SetDeltaWidthBits(uint64_t delta_width_bits) {
|
||||
delta_width_bits_ = delta_width_bits;
|
||||
delta_mask_ = MaxUnsignedValueOfBitWidth(delta_width_bits);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t delta_width_bits_; // Normally const, but mutable in tests.
|
||||
bool signed_deltas_; // Normally const, but mutable in tests.
|
||||
const bool values_optional_;
|
||||
const uint64_t value_width_bits_;
|
||||
|
||||
uint64_t delta_mask_; // Normally const, but mutable in tests.
|
||||
const uint64_t value_mask_;
|
||||
};
|
||||
|
||||
// Performs delta-encoding of a single (non-empty) sequence of values, using
|
||||
// an encoding where all deltas are encoded using the same number of bits.
|
||||
// (With the exception of optional elements; those are encoded as a bit vector
|
||||
// with one bit per element, plus a fixed number of bits for every element that
|
||||
// has a value.)
|
||||
class FixedLengthDeltaEncoder final {
|
||||
public:
|
||||
// See webrtc::EncodeDeltas() for general details.
|
||||
// This function return a bit pattern that would allow the decoder to
|
||||
// determine whether it was produced by FixedLengthDeltaEncoder, and can
|
||||
// therefore be decoded by FixedLengthDeltaDecoder, or whether it was produced
|
||||
// by a different encoder.
|
||||
static std::string EncodeDeltas(
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values);
|
||||
|
||||
FixedLengthDeltaEncoder(const FixedLengthDeltaEncoder&) = delete;
|
||||
FixedLengthDeltaEncoder& operator=(const FixedLengthDeltaEncoder&) = delete;
|
||||
|
||||
private:
|
||||
// Calculate min/max values of unsigned/signed deltas, given the bit width
|
||||
// of all the values in the series.
|
||||
static void CalculateMinAndMaxDeltas(
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values,
|
||||
uint64_t bit_width,
|
||||
uint64_t* max_unsigned_delta,
|
||||
uint64_t* max_pos_signed_delta,
|
||||
uint64_t* min_neg_signed_delta);
|
||||
|
||||
// No effect outside of unit tests.
|
||||
// In unit tests, may lead to forcing signed/unsigned deltas, etc.
|
||||
static void ConsiderTestOverrides(FixedLengthEncodingParameters* params,
|
||||
uint64_t delta_width_bits_signed,
|
||||
uint64_t delta_width_bits_unsigned);
|
||||
|
||||
// FixedLengthDeltaEncoder objects are to be created by EncodeDeltas() and
|
||||
// released by it before it returns. They're mostly a convenient way to
|
||||
// avoid having to pass a lot of state between different functions.
|
||||
// Therefore, it was deemed acceptable to let them have a reference to
|
||||
// `values`, whose lifetime must exceed the lifetime of `this`.
|
||||
FixedLengthDeltaEncoder(const FixedLengthEncodingParameters& params,
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values,
|
||||
size_t existent_values_count);
|
||||
|
||||
// Perform delta-encoding using the parameters given to the ctor on the
|
||||
// sequence of values given to the ctor.
|
||||
std::string Encode();
|
||||
|
||||
// Exact lengths.
|
||||
size_t OutputLengthBytes(size_t existent_values_count) const;
|
||||
size_t HeaderLengthBits() const;
|
||||
size_t EncodedDeltasLengthBits(size_t existent_values_count) const;
|
||||
|
||||
// Encode the compression parameters into the stream.
|
||||
void EncodeHeader();
|
||||
|
||||
// Encode a given delta into the stream.
|
||||
void EncodeDelta(uint64_t previous, uint64_t current);
|
||||
void EncodeUnsignedDelta(uint64_t previous, uint64_t current);
|
||||
void EncodeSignedDelta(uint64_t previous, uint64_t current);
|
||||
|
||||
// The parameters according to which encoding will be done (width of
|
||||
// fields, whether signed deltas should be used, etc.)
|
||||
const FixedLengthEncodingParameters params_;
|
||||
|
||||
// The encoding scheme assumes that at least one value is transmitted OOB,
|
||||
// so that the first value can be encoded as a delta from that OOB value,
|
||||
// which is `base_`.
|
||||
const absl::optional<uint64_t> base_;
|
||||
|
||||
// The values to be encoded.
|
||||
// Note: This is a non-owning reference. See comment above ctor for details.
|
||||
const std::vector<absl::optional<uint64_t>>& values_;
|
||||
|
||||
// Buffer into which encoded values will be written.
|
||||
// This is created dynmically as a way to enforce that the rest of the
|
||||
// ctor has finished running when this is constructed, so that the lower
|
||||
// bound on the buffer size would be guaranteed correct.
|
||||
std::unique_ptr<BitWriter> writer_;
|
||||
};
|
||||
|
||||
// TODO(eladalon): Reduce the number of passes.
|
||||
std::string FixedLengthDeltaEncoder::EncodeDeltas(
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values) {
|
||||
RTC_DCHECK(!values.empty());
|
||||
|
||||
// As a special case, if all of the elements are identical to the base,
|
||||
// (including, for optional fields, about their existence/non-existence),
|
||||
// the empty string is used to signal that.
|
||||
if (std::all_of(
|
||||
values.cbegin(), values.cend(),
|
||||
[base](absl::optional<uint64_t> val) { return val == base; })) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
bool non_decreasing = true;
|
||||
uint64_t max_value_including_base = base.value_or(0u);
|
||||
size_t existent_values_count = 0;
|
||||
{
|
||||
uint64_t previous = base.value_or(0u);
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
if (!values[i].has_value()) {
|
||||
continue;
|
||||
}
|
||||
++existent_values_count;
|
||||
non_decreasing &= (previous <= values[i].value());
|
||||
max_value_including_base =
|
||||
std::max(max_value_including_base, values[i].value());
|
||||
previous = values[i].value();
|
||||
}
|
||||
}
|
||||
|
||||
// If the sequence is non-decreasing, it may be assumed to have width = 64;
|
||||
// there's no reason to encode the actual max width in the encoding header.
|
||||
const uint64_t value_width_bits =
|
||||
non_decreasing ? 64 : UnsignedBitWidth(max_value_including_base);
|
||||
|
||||
uint64_t max_unsigned_delta;
|
||||
uint64_t max_pos_signed_delta;
|
||||
uint64_t min_neg_signed_delta;
|
||||
CalculateMinAndMaxDeltas(base, values, value_width_bits, &max_unsigned_delta,
|
||||
&max_pos_signed_delta, &min_neg_signed_delta);
|
||||
|
||||
const uint64_t delta_width_bits_unsigned =
|
||||
UnsignedBitWidth(max_unsigned_delta);
|
||||
const uint64_t delta_width_bits_signed =
|
||||
SignedBitWidth(max_pos_signed_delta, min_neg_signed_delta);
|
||||
|
||||
// Note: Preference for unsigned if the two have the same width (efficiency).
|
||||
const bool signed_deltas =
|
||||
delta_width_bits_signed < delta_width_bits_unsigned;
|
||||
const uint64_t delta_width_bits =
|
||||
signed_deltas ? delta_width_bits_signed : delta_width_bits_unsigned;
|
||||
|
||||
const bool values_optional =
|
||||
!base.has_value() || (existent_values_count < values.size());
|
||||
|
||||
FixedLengthEncodingParameters params(delta_width_bits, signed_deltas,
|
||||
values_optional, value_width_bits);
|
||||
|
||||
// No effect in production.
|
||||
ConsiderTestOverrides(¶ms, delta_width_bits_signed,
|
||||
delta_width_bits_unsigned);
|
||||
|
||||
FixedLengthDeltaEncoder encoder(params, base, values, existent_values_count);
|
||||
return encoder.Encode();
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::CalculateMinAndMaxDeltas(
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values,
|
||||
uint64_t bit_width,
|
||||
uint64_t* max_unsigned_delta_out,
|
||||
uint64_t* max_pos_signed_delta_out,
|
||||
uint64_t* min_neg_signed_delta_out) {
|
||||
RTC_DCHECK(!values.empty());
|
||||
RTC_DCHECK(max_unsigned_delta_out);
|
||||
RTC_DCHECK(max_pos_signed_delta_out);
|
||||
RTC_DCHECK(min_neg_signed_delta_out);
|
||||
|
||||
const uint64_t bit_mask = MaxUnsignedValueOfBitWidth(bit_width);
|
||||
|
||||
uint64_t max_unsigned_delta = 0;
|
||||
uint64_t max_pos_signed_delta = 0;
|
||||
uint64_t min_neg_signed_delta = 0;
|
||||
|
||||
absl::optional<uint64_t> prev = base;
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
if (!values[i].has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!prev.has_value()) {
|
||||
// If the base is non-existent, the first existent value is encoded as
|
||||
// a varint, rather than as a delta.
|
||||
RTC_DCHECK(!base.has_value());
|
||||
prev = values[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint64_t current = values[i].value();
|
||||
|
||||
const uint64_t forward_delta = UnsignedDelta(*prev, current, bit_mask);
|
||||
const uint64_t backward_delta = UnsignedDelta(current, *prev, bit_mask);
|
||||
|
||||
max_unsigned_delta = std::max(max_unsigned_delta, forward_delta);
|
||||
|
||||
if (forward_delta < backward_delta) {
|
||||
max_pos_signed_delta = std::max(max_pos_signed_delta, forward_delta);
|
||||
} else {
|
||||
min_neg_signed_delta = std::max(min_neg_signed_delta, backward_delta);
|
||||
}
|
||||
|
||||
prev = current;
|
||||
}
|
||||
|
||||
*max_unsigned_delta_out = max_unsigned_delta;
|
||||
*max_pos_signed_delta_out = max_pos_signed_delta;
|
||||
*min_neg_signed_delta_out = min_neg_signed_delta;
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::ConsiderTestOverrides(
|
||||
FixedLengthEncodingParameters* params,
|
||||
uint64_t delta_width_bits_signed,
|
||||
uint64_t delta_width_bits_unsigned) {
|
||||
if (g_force_unsigned_for_testing) {
|
||||
params->SetDeltaWidthBits(delta_width_bits_unsigned);
|
||||
params->SetSignedDeltas(false);
|
||||
} else if (g_force_signed_for_testing) {
|
||||
params->SetDeltaWidthBits(delta_width_bits_signed);
|
||||
params->SetSignedDeltas(true);
|
||||
} else {
|
||||
// Unchanged.
|
||||
}
|
||||
}
|
||||
|
||||
FixedLengthDeltaEncoder::FixedLengthDeltaEncoder(
|
||||
const FixedLengthEncodingParameters& params,
|
||||
absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values,
|
||||
size_t existent_values_count)
|
||||
: params_(params), base_(base), values_(values) {
|
||||
RTC_DCHECK(!values_.empty());
|
||||
writer_ =
|
||||
std::make_unique<BitWriter>(OutputLengthBytes(existent_values_count));
|
||||
}
|
||||
|
||||
std::string FixedLengthDeltaEncoder::Encode() {
|
||||
EncodeHeader();
|
||||
|
||||
if (params_.values_optional()) {
|
||||
// Encode which values exist and which don't.
|
||||
for (absl::optional<uint64_t> value : values_) {
|
||||
writer_->WriteBits(value.has_value() ? 1u : 0u, 1);
|
||||
}
|
||||
}
|
||||
|
||||
absl::optional<uint64_t> previous = base_;
|
||||
for (absl::optional<uint64_t> value : values_) {
|
||||
if (!value.has_value()) {
|
||||
RTC_DCHECK(params_.values_optional());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!previous.has_value()) {
|
||||
// If the base is non-existent, the first existent value is encoded as
|
||||
// a varint, rather than as a delta.
|
||||
RTC_DCHECK(!base_.has_value());
|
||||
writer_->WriteBits(EncodeVarInt(value.value()));
|
||||
} else {
|
||||
EncodeDelta(previous.value(), value.value());
|
||||
}
|
||||
|
||||
previous = value;
|
||||
}
|
||||
|
||||
return writer_->GetString();
|
||||
}
|
||||
|
||||
size_t FixedLengthDeltaEncoder::OutputLengthBytes(
|
||||
size_t existent_values_count) const {
|
||||
return BitsToBytes(HeaderLengthBits() +
|
||||
EncodedDeltasLengthBits(existent_values_count));
|
||||
}
|
||||
|
||||
size_t FixedLengthDeltaEncoder::HeaderLengthBits() const {
|
||||
if (params_.signed_deltas() == kDefaultSignedDeltas &&
|
||||
params_.values_optional() == kDefaultValuesOptional &&
|
||||
params_.value_width_bits() == kDefaultValueWidthBits) {
|
||||
return kBitsInHeaderForEncodingType + kBitsInHeaderForDeltaWidthBits;
|
||||
} else {
|
||||
return kBitsInHeaderForEncodingType + kBitsInHeaderForDeltaWidthBits +
|
||||
kBitsInHeaderForSignedDeltas + kBitsInHeaderForValuesOptional +
|
||||
kBitsInHeaderForValueWidthBits;
|
||||
}
|
||||
}
|
||||
|
||||
size_t FixedLengthDeltaEncoder::EncodedDeltasLengthBits(
|
||||
size_t existent_values_count) const {
|
||||
if (!params_.values_optional()) {
|
||||
return values_.size() * params_.delta_width_bits();
|
||||
} else {
|
||||
RTC_DCHECK_EQ(std::count_if(values_.begin(), values_.end(),
|
||||
[](absl::optional<uint64_t> val) {
|
||||
return val.has_value();
|
||||
}),
|
||||
existent_values_count);
|
||||
// One bit for each delta, to indicate if the value exists, and delta_width
|
||||
// for each existent value, to indicate the delta itself.
|
||||
// If base_ is non-existent, the first value (if any) is encoded as a varint
|
||||
// rather than as a delta.
|
||||
const size_t existence_bitmap_size_bits = 1 * values_.size();
|
||||
const bool first_value_is_varint =
|
||||
!base_.has_value() && existent_values_count >= 1;
|
||||
const size_t first_value_varint_size_bits = 8 * kMaxVarIntLengthBytes;
|
||||
const size_t deltas_count = existent_values_count - first_value_is_varint;
|
||||
const size_t deltas_size_bits = deltas_count * params_.delta_width_bits();
|
||||
return existence_bitmap_size_bits + first_value_varint_size_bits +
|
||||
deltas_size_bits;
|
||||
}
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::EncodeHeader() {
|
||||
RTC_DCHECK(writer_);
|
||||
|
||||
const EncodingType encoding_type =
|
||||
(params_.value_width_bits() == kDefaultValueWidthBits &&
|
||||
params_.signed_deltas() == kDefaultSignedDeltas &&
|
||||
params_.values_optional() == kDefaultValuesOptional)
|
||||
? EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt
|
||||
: EncodingType::kFixedSizeSignedDeltasEarlyWrapAndOptSupported;
|
||||
|
||||
writer_->WriteBits(static_cast<uint64_t>(encoding_type),
|
||||
kBitsInHeaderForEncodingType);
|
||||
|
||||
// Note: Since it's meaningless for a field to be of width 0, when it comes
|
||||
// to fields that relate widths, we encode width 1 as 0, width 2 as 1,
|
||||
|
||||
writer_->WriteBits(params_.delta_width_bits() - 1,
|
||||
kBitsInHeaderForDeltaWidthBits);
|
||||
|
||||
if (encoding_type == EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
writer_->WriteBits(static_cast<uint64_t>(params_.signed_deltas()),
|
||||
kBitsInHeaderForSignedDeltas);
|
||||
writer_->WriteBits(static_cast<uint64_t>(params_.values_optional()),
|
||||
kBitsInHeaderForValuesOptional);
|
||||
writer_->WriteBits(params_.value_width_bits() - 1,
|
||||
kBitsInHeaderForValueWidthBits);
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::EncodeDelta(uint64_t previous, uint64_t current) {
|
||||
if (params_.signed_deltas()) {
|
||||
EncodeSignedDelta(previous, current);
|
||||
} else {
|
||||
EncodeUnsignedDelta(previous, current);
|
||||
}
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::EncodeUnsignedDelta(uint64_t previous,
|
||||
uint64_t current) {
|
||||
RTC_DCHECK(writer_);
|
||||
const uint64_t delta = UnsignedDelta(previous, current, params_.value_mask());
|
||||
writer_->WriteBits(delta, params_.delta_width_bits());
|
||||
}
|
||||
|
||||
void FixedLengthDeltaEncoder::EncodeSignedDelta(uint64_t previous,
|
||||
uint64_t current) {
|
||||
RTC_DCHECK(writer_);
|
||||
|
||||
const uint64_t forward_delta =
|
||||
UnsignedDelta(previous, current, params_.value_mask());
|
||||
const uint64_t backward_delta =
|
||||
UnsignedDelta(current, previous, params_.value_mask());
|
||||
|
||||
uint64_t delta;
|
||||
if (forward_delta <= backward_delta) {
|
||||
delta = forward_delta;
|
||||
} else {
|
||||
// Compute the unsigned representation of a negative delta.
|
||||
// This is the two's complement representation of this negative value,
|
||||
// when deltas are of width params_.delta_mask().
|
||||
RTC_DCHECK_GE(params_.delta_mask(), backward_delta);
|
||||
RTC_DCHECK_LT(params_.delta_mask() - backward_delta, params_.delta_mask());
|
||||
delta = params_.delta_mask() - backward_delta + 1;
|
||||
RTC_DCHECK_LE(delta, params_.delta_mask());
|
||||
}
|
||||
|
||||
writer_->WriteBits(delta, params_.delta_width_bits());
|
||||
}
|
||||
|
||||
// Perform decoding of a a delta-encoded stream, extracting the original
|
||||
// sequence of values.
|
||||
class FixedLengthDeltaDecoder final {
|
||||
public:
|
||||
// Checks whether FixedLengthDeltaDecoder is a suitable decoder for this
|
||||
// bitstream. Note that this does NOT imply that stream is valid, and will
|
||||
// be decoded successfully. It DOES imply that all other decoder classes
|
||||
// will fail to decode this input, though.
|
||||
static bool IsSuitableDecoderFor(absl::string_view input);
|
||||
|
||||
// Assuming that `input` is the result of fixed-size delta-encoding
|
||||
// that took place with the same value to `base` and over `num_of_deltas`
|
||||
// original values, this will return the sequence of original values.
|
||||
// If an error occurs (can happen if `input` is corrupt), an empty
|
||||
// vector will be returned.
|
||||
static std::vector<absl::optional<uint64_t>> DecodeDeltas(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas);
|
||||
|
||||
FixedLengthDeltaDecoder(const FixedLengthDeltaDecoder&) = delete;
|
||||
FixedLengthDeltaDecoder& operator=(const FixedLengthDeltaDecoder&) = delete;
|
||||
|
||||
private:
|
||||
// Reads the encoding header in `input` and returns a FixedLengthDeltaDecoder
|
||||
// with the corresponding configuration, that can be used to decode the
|
||||
// values in `input`.
|
||||
// If the encoding header is corrupt (contains an illegal configuration),
|
||||
// nullptr will be returned.
|
||||
// When a valid FixedLengthDeltaDecoder is returned, this does not mean that
|
||||
// the entire stream is free of error. Rather, only the encoding header is
|
||||
// examined and guaranteed.
|
||||
static std::unique_ptr<FixedLengthDeltaDecoder> Create(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas);
|
||||
|
||||
// FixedLengthDeltaDecoder objects are to be created by DecodeDeltas() and
|
||||
// released by it before it returns. They're mostly a convenient way to
|
||||
// avoid having to pass a lot of state between different functions.
|
||||
// Therefore, it was deemed acceptable that `reader` does not own the buffer
|
||||
// it reads, meaning the lifetime of `this` must not exceed the lifetime
|
||||
// of `reader`'s underlying buffer.
|
||||
FixedLengthDeltaDecoder(BitstreamReader reader,
|
||||
const FixedLengthEncodingParameters& params,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas);
|
||||
|
||||
// Perform the decoding using the parameters given to the ctor.
|
||||
std::vector<absl::optional<uint64_t>> Decode();
|
||||
|
||||
// Add `delta` to `base` to produce the next value in a sequence.
|
||||
// The delta is applied as signed/unsigned depending on the parameters
|
||||
// given to the ctor. Wrap-around is taken into account according to the
|
||||
// values' width, as specified by the aforementioned encoding parameters.
|
||||
uint64_t ApplyDelta(uint64_t base, uint64_t delta) const;
|
||||
|
||||
// Helpers for ApplyDelta().
|
||||
uint64_t ApplyUnsignedDelta(uint64_t base, uint64_t delta) const;
|
||||
uint64_t ApplySignedDelta(uint64_t base, uint64_t delta) const;
|
||||
|
||||
// Reader of the input stream to be decoded. Does not own that buffer.
|
||||
// See comment above ctor for details.
|
||||
BitstreamReader reader_;
|
||||
|
||||
// The parameters according to which encoding will be done (width of
|
||||
// fields, whether signed deltas should be used, etc.)
|
||||
const FixedLengthEncodingParameters params_;
|
||||
|
||||
// The encoding scheme assumes that at least one value is transmitted OOB,
|
||||
// so that the first value can be encoded as a delta from that OOB value,
|
||||
// which is `base_`.
|
||||
const absl::optional<uint64_t> base_;
|
||||
|
||||
// The number of values to be known to be decoded.
|
||||
const size_t num_of_deltas_;
|
||||
};
|
||||
|
||||
bool FixedLengthDeltaDecoder::IsSuitableDecoderFor(absl::string_view input) {
|
||||
BitstreamReader reader(input);
|
||||
uint64_t encoding_type_bits = reader.ReadBits(kBitsInHeaderForEncodingType);
|
||||
if (!reader.Ok()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto encoding_type = static_cast<EncodingType>(encoding_type_bits);
|
||||
return encoding_type ==
|
||||
EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt ||
|
||||
encoding_type ==
|
||||
EncodingType::kFixedSizeSignedDeltasEarlyWrapAndOptSupported;
|
||||
}
|
||||
|
||||
std::vector<absl::optional<uint64_t>> FixedLengthDeltaDecoder::DecodeDeltas(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas) {
|
||||
auto decoder = FixedLengthDeltaDecoder::Create(input, base, num_of_deltas);
|
||||
if (!decoder) {
|
||||
return std::vector<absl::optional<uint64_t>>();
|
||||
}
|
||||
|
||||
return decoder->Decode();
|
||||
}
|
||||
|
||||
std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas) {
|
||||
BitstreamReader reader(input);
|
||||
// Encoding type
|
||||
uint32_t encoding_type_bits = reader.ReadBits(kBitsInHeaderForEncodingType);
|
||||
if (!reader.Ok()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const EncodingType encoding = static_cast<EncodingType>(encoding_type_bits);
|
||||
if (encoding != EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt &&
|
||||
encoding !=
|
||||
EncodingType::kFixedSizeSignedDeltasEarlyWrapAndOptSupported) {
|
||||
RTC_LOG(LS_WARNING) << "Unrecognized encoding type.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// See encoding for +1's rationale.
|
||||
const uint64_t delta_width_bits =
|
||||
reader.ReadBits(kBitsInHeaderForDeltaWidthBits) + 1;
|
||||
RTC_DCHECK_LE(delta_width_bits, 64);
|
||||
|
||||
// signed_deltas, values_optional, value_width_bits
|
||||
bool signed_deltas;
|
||||
bool values_optional;
|
||||
uint64_t value_width_bits;
|
||||
if (encoding == EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt) {
|
||||
signed_deltas = kDefaultSignedDeltas;
|
||||
values_optional = kDefaultValuesOptional;
|
||||
value_width_bits = kDefaultValueWidthBits;
|
||||
} else {
|
||||
signed_deltas = reader.Read<bool>();
|
||||
values_optional = reader.Read<bool>();
|
||||
// See encoding for +1's rationale.
|
||||
value_width_bits = reader.ReadBits(kBitsInHeaderForValueWidthBits) + 1;
|
||||
RTC_DCHECK_LE(value_width_bits, 64);
|
||||
}
|
||||
|
||||
if (!reader.Ok()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Note: Because of the way the parameters are read, it is not possible
|
||||
// for illegal values to be read. We check nevertheless, in case the code
|
||||
// changes in the future in a way that breaks this promise.
|
||||
if (!FixedLengthEncodingParameters::ValidParameters(
|
||||
delta_width_bits, signed_deltas, values_optional, value_width_bits)) {
|
||||
RTC_LOG(LS_WARNING) << "Corrupt log; illegal encoding parameters.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FixedLengthEncodingParameters params(delta_width_bits, signed_deltas,
|
||||
values_optional, value_width_bits);
|
||||
return absl::WrapUnique(
|
||||
new FixedLengthDeltaDecoder(reader, params, base, num_of_deltas));
|
||||
}
|
||||
|
||||
FixedLengthDeltaDecoder::FixedLengthDeltaDecoder(
|
||||
BitstreamReader reader,
|
||||
const FixedLengthEncodingParameters& params,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas)
|
||||
: reader_(reader),
|
||||
params_(params),
|
||||
base_(base),
|
||||
num_of_deltas_(num_of_deltas) {
|
||||
RTC_DCHECK(reader_.Ok());
|
||||
}
|
||||
|
||||
std::vector<absl::optional<uint64_t>> FixedLengthDeltaDecoder::Decode() {
|
||||
RTC_DCHECK(reader_.Ok());
|
||||
std::vector<bool> existing_values(num_of_deltas_);
|
||||
if (params_.values_optional()) {
|
||||
for (size_t i = 0; i < num_of_deltas_; ++i) {
|
||||
existing_values[i] = reader_.Read<bool>();
|
||||
}
|
||||
} else {
|
||||
std::fill(existing_values.begin(), existing_values.end(), true);
|
||||
}
|
||||
|
||||
absl::optional<uint64_t> previous = base_;
|
||||
std::vector<absl::optional<uint64_t>> values(num_of_deltas_);
|
||||
|
||||
for (size_t i = 0; i < num_of_deltas_; ++i) {
|
||||
if (!existing_values[i]) {
|
||||
RTC_DCHECK(params_.values_optional());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!previous) {
|
||||
// If the base is non-existent, the first existent value is encoded as
|
||||
// a varint, rather than as a delta.
|
||||
RTC_DCHECK(!base_.has_value());
|
||||
values[i] = DecodeVarInt(reader_);
|
||||
} else {
|
||||
uint64_t delta = reader_.ReadBits(params_.delta_width_bits());
|
||||
values[i] = ApplyDelta(*previous, delta);
|
||||
}
|
||||
|
||||
previous = values[i];
|
||||
}
|
||||
|
||||
if (!reader_.Ok()) {
|
||||
values = {};
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
uint64_t FixedLengthDeltaDecoder::ApplyDelta(uint64_t base,
|
||||
uint64_t delta) const {
|
||||
RTC_DCHECK_LE(base, MaxUnsignedValueOfBitWidth(params_.value_width_bits()));
|
||||
RTC_DCHECK_LE(delta, MaxUnsignedValueOfBitWidth(params_.delta_width_bits()));
|
||||
return params_.signed_deltas() ? ApplySignedDelta(base, delta)
|
||||
: ApplyUnsignedDelta(base, delta);
|
||||
}
|
||||
|
||||
uint64_t FixedLengthDeltaDecoder::ApplyUnsignedDelta(uint64_t base,
|
||||
uint64_t delta) const {
|
||||
// Note: May still be used if signed deltas used.
|
||||
RTC_DCHECK_LE(base, MaxUnsignedValueOfBitWidth(params_.value_width_bits()));
|
||||
RTC_DCHECK_LE(delta, MaxUnsignedValueOfBitWidth(params_.delta_width_bits()));
|
||||
return (base + delta) & params_.value_mask();
|
||||
}
|
||||
|
||||
uint64_t FixedLengthDeltaDecoder::ApplySignedDelta(uint64_t base,
|
||||
uint64_t delta) const {
|
||||
RTC_DCHECK(params_.signed_deltas());
|
||||
RTC_DCHECK_LE(base, MaxUnsignedValueOfBitWidth(params_.value_width_bits()));
|
||||
RTC_DCHECK_LE(delta, MaxUnsignedValueOfBitWidth(params_.delta_width_bits()));
|
||||
|
||||
const uint64_t top_bit = static_cast<uint64_t>(1)
|
||||
<< (params_.delta_width_bits() - 1);
|
||||
|
||||
const bool positive_delta = ((delta & top_bit) == 0);
|
||||
if (positive_delta) {
|
||||
return ApplyUnsignedDelta(base, delta);
|
||||
}
|
||||
|
||||
const uint64_t delta_abs = (~delta & params_.delta_mask()) + 1;
|
||||
return (base - delta_abs) & params_.value_mask();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string EncodeDeltas(absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values) {
|
||||
// TODO(eladalon): Support additional encodings.
|
||||
return FixedLengthDeltaEncoder::EncodeDeltas(base, values);
|
||||
}
|
||||
|
||||
std::vector<absl::optional<uint64_t>> DecodeDeltas(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas) {
|
||||
RTC_DCHECK_GT(num_of_deltas, 0); // Allows empty vector to indicate error.
|
||||
|
||||
// The empty string is a special case indicating that all values were equal
|
||||
// to the base.
|
||||
if (input.empty()) {
|
||||
std::vector<absl::optional<uint64_t>> result(num_of_deltas);
|
||||
std::fill(result.begin(), result.end(), base);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (FixedLengthDeltaDecoder::IsSuitableDecoderFor(input)) {
|
||||
return FixedLengthDeltaDecoder::DecodeDeltas(input, base, num_of_deltas);
|
||||
}
|
||||
|
||||
RTC_LOG(LS_WARNING) << "Could not decode delta-encoded stream.";
|
||||
return std::vector<absl::optional<uint64_t>>();
|
||||
}
|
||||
|
||||
void SetFixedLengthEncoderDeltaSignednessForTesting(bool signedness) {
|
||||
g_force_unsigned_for_testing = !signedness;
|
||||
g_force_signed_for_testing = signedness;
|
||||
}
|
||||
|
||||
void UnsetFixedLengthEncoderDeltaSignednessForTesting() {
|
||||
g_force_unsigned_for_testing = false;
|
||||
g_force_signed_for_testing = false;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_ENCODER_DELTA_ENCODING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_DELTA_ENCODING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Encode `values` as a sequence of deltas following on `base` and return it.
|
||||
// If all of the values were equal to the base, an empty string will be
|
||||
// returned; this is a valid encoding of that edge case.
|
||||
// `base` is not guaranteed to be written into `output`, and must therefore
|
||||
// be provided separately to the decoder.
|
||||
// This function never fails.
|
||||
// TODO(eladalon): Split into optional and non-optional variants (efficiency).
|
||||
std::string EncodeDeltas(absl::optional<uint64_t> base,
|
||||
const std::vector<absl::optional<uint64_t>>& values);
|
||||
|
||||
// EncodeDeltas() and DecodeDeltas() are inverse operations;
|
||||
// invoking DecodeDeltas() over the output of EncodeDeltas(), will return
|
||||
// the input originally given to EncodeDeltas().
|
||||
// `num_of_deltas` must be greater than zero. If input is not a valid encoding
|
||||
// of `num_of_deltas` elements based on `base`, the function returns an empty
|
||||
// vector, which signals an error.
|
||||
// TODO(eladalon): Split into optional and non-optional variants (efficiency).
|
||||
std::vector<absl::optional<uint64_t>> DecodeDeltas(
|
||||
absl::string_view input,
|
||||
absl::optional<uint64_t> base,
|
||||
size_t num_of_deltas);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_DELTA_ENCODING_H_
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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/encoder/optional_blob_encoding.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "rtc_base/bit_buffer.h"
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string EncodeOptionalBlobs(
|
||||
const std::vector<absl::optional<std::string>>& blobs) {
|
||||
if (blobs.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t reserve_size_bits = 1;
|
||||
size_t num_blobs_present = 0;
|
||||
for (const auto& blob : blobs) {
|
||||
if (blob.has_value()) {
|
||||
++num_blobs_present;
|
||||
reserve_size_bits +=
|
||||
(rtc::BitBufferWriter::kMaxLeb128Length.bytes() + blob->size()) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_blobs_present == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const bool all_blobs_present = num_blobs_present == blobs.size();
|
||||
if (!all_blobs_present) {
|
||||
reserve_size_bits += blobs.size();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buffer((reserve_size_bits + 7) / 8);
|
||||
rtc::BitBufferWriter writer(buffer.data(), buffer.size());
|
||||
|
||||
// Write present bits if all blobs are not present.
|
||||
writer.WriteBits(all_blobs_present, 1);
|
||||
if (!all_blobs_present) {
|
||||
for (const auto& blob : blobs) {
|
||||
writer.WriteBits(blob.has_value(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Byte align the writer.
|
||||
writer.ConsumeBits(writer.RemainingBitCount() % 8);
|
||||
|
||||
// Write blobs.
|
||||
for (const auto& blob : blobs) {
|
||||
if (blob.has_value()) {
|
||||
writer.WriteLeb128(blob->length());
|
||||
writer.WriteString(*blob);
|
||||
}
|
||||
}
|
||||
|
||||
size_t bytes_written;
|
||||
size_t bits_written;
|
||||
writer.GetCurrentOffset(&bytes_written, &bits_written);
|
||||
RTC_CHECK_EQ(bits_written, 0);
|
||||
RTC_CHECK_LE(bytes_written, buffer.size());
|
||||
|
||||
return std::string(buffer.data(), buffer.data() + bytes_written);
|
||||
}
|
||||
|
||||
std::vector<absl::optional<std::string>> DecodeOptionalBlobs(
|
||||
absl::string_view encoded_blobs,
|
||||
size_t num_of_blobs) {
|
||||
std::vector<absl::optional<std::string>> res(num_of_blobs);
|
||||
if (encoded_blobs.empty() || num_of_blobs == 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
BitstreamReader reader(encoded_blobs);
|
||||
const bool all_blobs_present = reader.ReadBit();
|
||||
|
||||
// Read present bits if all blobs are not present.
|
||||
std::vector<uint8_t> present;
|
||||
if (!all_blobs_present) {
|
||||
present.resize(num_of_blobs);
|
||||
for (size_t i = 0; i < num_of_blobs; ++i) {
|
||||
present[i] = reader.ReadBit();
|
||||
}
|
||||
}
|
||||
|
||||
// Byte align the reader.
|
||||
reader.ConsumeBits(reader.RemainingBitCount() % 8);
|
||||
|
||||
// Read the blobs.
|
||||
for (size_t i = 0; i < num_of_blobs; ++i) {
|
||||
if (!all_blobs_present && !present[i]) {
|
||||
continue;
|
||||
}
|
||||
res[i] = reader.ReadString(reader.ReadLeb128());
|
||||
}
|
||||
|
||||
// The result is only valid if exactly all bits was consumed during decoding.
|
||||
if (!reader.Ok() || reader.RemainingBitCount() > 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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_ENCODER_OPTIONAL_BLOB_ENCODING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_OPTIONAL_BLOB_ENCODING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Encode a sequence of optional strings, whose length is not known to be
|
||||
// discernable from the blob itself (i.e. without being transmitted OOB),
|
||||
// in a way that would allow us to separate them again on the decoding side.
|
||||
// EncodeOptionalBlobs() may not fail but may return an empty string
|
||||
std::string EncodeOptionalBlobs(
|
||||
const std::vector<absl::optional<std::string>>& blobs);
|
||||
|
||||
// Calling DecodeOptionalBlobs() on an empty string, or with `num_of_blobs` set
|
||||
// to 0, is an error. DecodeOptionalBlobs() returns an empty vector if it fails,
|
||||
// which can happen if `encoded_blobs` is corrupted.
|
||||
std::vector<absl::optional<std::string>> DecodeOptionalBlobs(
|
||||
absl::string_view encoded_blobs,
|
||||
size_t num_of_blobs);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_OPTIONAL_BLOB_ENCODING_H_
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ENCODER_RTC_EVENT_LOG_ENCODER_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_H_
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
|
||||
namespace webrtc {
|
||||
class RtcEventLogEncoder {
|
||||
public:
|
||||
virtual ~RtcEventLogEncoder() = default;
|
||||
|
||||
virtual std::string EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) = 0;
|
||||
virtual std::string EncodeLogEnd(int64_t timestamp_us) = 0;
|
||||
|
||||
virtual std::string EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_H_
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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/encoder/rtc_event_log_encoder_common.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
// We use 0x3fff because that gives decent precision (compared to the underlying
|
||||
// measurement producing the packet loss fraction) on the one hand, while
|
||||
// allowing us to use no more than 2 bytes in varint form on the other hand.
|
||||
// (We might also fixed-size encode using at most 14 bits.)
|
||||
constexpr uint32_t kPacketLossFractionRange = (1 << 14) - 1; // 0x3fff
|
||||
constexpr float kPacketLossFractionRangeFloat =
|
||||
static_cast<float>(kPacketLossFractionRange);
|
||||
} // namespace
|
||||
|
||||
uint32_t ConvertPacketLossFractionToProtoFormat(float packet_loss_fraction) {
|
||||
RTC_DCHECK_GE(packet_loss_fraction, 0);
|
||||
RTC_DCHECK_LE(packet_loss_fraction, 1);
|
||||
return static_cast<uint32_t>(packet_loss_fraction * kPacketLossFractionRange);
|
||||
}
|
||||
|
||||
bool ParsePacketLossFractionFromProtoFormat(uint32_t proto_packet_loss_fraction,
|
||||
float* output) {
|
||||
if (proto_packet_loss_fraction >= kPacketLossFractionRange) {
|
||||
return false;
|
||||
}
|
||||
*output = proto_packet_loss_fraction / kPacketLossFractionRangeFloat;
|
||||
return true;
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_ENCODER_RTC_EVENT_LOG_ENCODER_COMMON_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Convert between the packet fraction loss (a floating point number in
|
||||
// the range [0.0, 1.0]), and a uint32_t with up to a fixed number of bits.
|
||||
// The latter can be more efficiently stored in a protobuf and/or delta-encoded.
|
||||
uint32_t ConvertPacketLossFractionToProtoFormat(float packet_loss_fraction);
|
||||
bool ParsePacketLossFractionFromProtoFormat(uint32_t proto_packet_loss_fraction,
|
||||
float* output);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
namespace webrtc_event_logging {
|
||||
|
||||
// Produce an unsigned representation of a signed integer. On two's complement
|
||||
// machines, this is equivalent to:
|
||||
// static_cast<uint64_t>(static_cast<std::make_unsigned<T>>(y))
|
||||
template <typename T>
|
||||
uint64_t ToUnsigned(T y) {
|
||||
static_assert(std::is_integral<T>::value, "");
|
||||
static_assert(std::is_signed<T>::value, "");
|
||||
|
||||
// Note that a signed integer whose width is N bits, has N-1 digits.
|
||||
static_assert(std::numeric_limits<T>::digits < 64, "");
|
||||
|
||||
constexpr T MIN_T = std::numeric_limits<T>::min();
|
||||
constexpr T MAX_T = std::numeric_limits<T>::max();
|
||||
|
||||
static_assert(MAX_T + MIN_T + 1 >= 0, "MAX_T >= abs(MIN_T) - 1");
|
||||
|
||||
if (y >= 0) {
|
||||
return static_cast<uint64_t>(y);
|
||||
} else {
|
||||
// y is in the range [MIN_T, -1], so (y - MIN_T) is in the
|
||||
// range [0, abs(MIN_T) - 1]. This is representable in a T
|
||||
// because MAX_T >= abs(MIN_T) - 1, as per the static_assert above.
|
||||
return static_cast<uint64_t>(MAX_T) + 1 + static_cast<uint64_t>(y - MIN_T);
|
||||
}
|
||||
}
|
||||
|
||||
// Assuming x = ToUnsigned(y), return `y`.
|
||||
// Note: static_cast<T>(x) would work on most platforms and compilers, but
|
||||
// involves undefined behavior. This function is well-defined, and can be
|
||||
// optimized to a noop for 64 bit types, or a few arithmetic
|
||||
// instructions and a single conditional jump for narrower types.
|
||||
template <typename T>
|
||||
bool ToSigned(uint64_t x, T* y) {
|
||||
static_assert(std::is_integral<T>::value, "");
|
||||
static_assert(std::is_signed<T>::value, "");
|
||||
|
||||
// Note that a signed integer whose width is N bits, has N-1 digits.
|
||||
static_assert(std::numeric_limits<T>::digits < 64, "");
|
||||
|
||||
constexpr T MIN_T = std::numeric_limits<T>::min();
|
||||
constexpr T MAX_T = std::numeric_limits<T>::max();
|
||||
|
||||
using UNSIGNED_T = typename std::make_unsigned<T>::type;
|
||||
constexpr auto MAX_UNSIGNED_T = std::numeric_limits<UNSIGNED_T>::max();
|
||||
if (x > static_cast<uint64_t>(MAX_UNSIGNED_T)) {
|
||||
return false; // `x` cannot be represented using a T.
|
||||
}
|
||||
|
||||
if (x <= static_cast<uint64_t>(MAX_T)) {
|
||||
// The original value was positive, so it is safe to just static_cast.
|
||||
*y = static_cast<T>(x);
|
||||
} else { // x > static_cast<uint64_t>(MAX_T)
|
||||
const uint64_t neg_x = x - static_cast<uint64_t>(MAX_T) - 1;
|
||||
*y = static_cast<T>(neg_x) + MIN_T;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc_event_logging
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_COMMON_H_
|
||||
|
|
@ -0,0 +1,806 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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/encoder/rtc_event_log_encoder_legacy.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/rtp_headers.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
|
||||
#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_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_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_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"
|
||||
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
// *.pb.h files are generated at build-time by the protobuf compiler.
|
||||
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
|
||||
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
|
||||
#else
|
||||
#include "logging/rtc_event_log/rtc_event_log.pb.h"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState(
|
||||
BandwidthUsage state) {
|
||||
switch (state) {
|
||||
case BandwidthUsage::kBwNormal:
|
||||
return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
|
||||
case BandwidthUsage::kBwUnderusing:
|
||||
return rtclog::DelayBasedBweUpdate::BWE_UNDERUSING;
|
||||
case BandwidthUsage::kBwOverusing:
|
||||
return rtclog::DelayBasedBweUpdate::BWE_OVERUSING;
|
||||
case BandwidthUsage::kLast:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
|
||||
}
|
||||
|
||||
rtclog::BweProbeResult::ResultType ConvertProbeResultType(
|
||||
ProbeFailureReason failure_reason) {
|
||||
switch (failure_reason) {
|
||||
case ProbeFailureReason::kInvalidSendReceiveInterval:
|
||||
return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL;
|
||||
case ProbeFailureReason::kInvalidSendReceiveRatio:
|
||||
return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO;
|
||||
case ProbeFailureReason::kTimeout:
|
||||
return rtclog::BweProbeResult::TIMEOUT;
|
||||
case ProbeFailureReason::kLast:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::BweProbeResult::SUCCESS;
|
||||
}
|
||||
|
||||
rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
|
||||
switch (rtcp_mode) {
|
||||
case RtcpMode::kCompound:
|
||||
return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
|
||||
case RtcpMode::kReducedSize:
|
||||
return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE;
|
||||
case RtcpMode::kOff:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairConfig::IceCandidatePairConfigType
|
||||
ConvertIceCandidatePairConfigType(IceCandidatePairConfigType type) {
|
||||
switch (type) {
|
||||
case IceCandidatePairConfigType::kAdded:
|
||||
return rtclog::IceCandidatePairConfig::ADDED;
|
||||
case IceCandidatePairConfigType::kUpdated:
|
||||
return rtclog::IceCandidatePairConfig::UPDATED;
|
||||
case IceCandidatePairConfigType::kDestroyed:
|
||||
return rtclog::IceCandidatePairConfig::DESTROYED;
|
||||
case IceCandidatePairConfigType::kSelected:
|
||||
return rtclog::IceCandidatePairConfig::SELECTED;
|
||||
case IceCandidatePairConfigType::kNumValues:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::IceCandidatePairConfig::ADDED;
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType(
|
||||
IceCandidateType type) {
|
||||
switch (type) {
|
||||
case IceCandidateType::kHost:
|
||||
return rtclog::IceCandidatePairConfig::LOCAL;
|
||||
case IceCandidateType::kSrflx:
|
||||
return rtclog::IceCandidatePairConfig::STUN;
|
||||
case IceCandidateType::kPrflx:
|
||||
return rtclog::IceCandidatePairConfig::PRFLX;
|
||||
case IceCandidateType::kRelay:
|
||||
return rtclog::IceCandidatePairConfig::RELAY;
|
||||
}
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairConfig::Protocol ConvertIceCandidatePairProtocol(
|
||||
IceCandidatePairProtocol protocol) {
|
||||
switch (protocol) {
|
||||
case IceCandidatePairProtocol::kUnknown:
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
|
||||
case IceCandidatePairProtocol::kUdp:
|
||||
return rtclog::IceCandidatePairConfig::UDP;
|
||||
case IceCandidatePairProtocol::kTcp:
|
||||
return rtclog::IceCandidatePairConfig::TCP;
|
||||
case IceCandidatePairProtocol::kSsltcp:
|
||||
return rtclog::IceCandidatePairConfig::SSLTCP;
|
||||
case IceCandidatePairProtocol::kTls:
|
||||
return rtclog::IceCandidatePairConfig::TLS;
|
||||
case IceCandidatePairProtocol::kNumValues:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairConfig::AddressFamily
|
||||
ConvertIceCandidatePairAddressFamily(
|
||||
IceCandidatePairAddressFamily address_family) {
|
||||
switch (address_family) {
|
||||
case IceCandidatePairAddressFamily::kUnknown:
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
|
||||
case IceCandidatePairAddressFamily::kIpv4:
|
||||
return rtclog::IceCandidatePairConfig::IPV4;
|
||||
case IceCandidatePairAddressFamily::kIpv6:
|
||||
return rtclog::IceCandidatePairConfig::IPV6;
|
||||
case IceCandidatePairAddressFamily::kNumValues:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairConfig::NetworkType ConvertIceCandidateNetworkType(
|
||||
IceCandidateNetworkType network_type) {
|
||||
switch (network_type) {
|
||||
case IceCandidateNetworkType::kUnknown:
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
|
||||
case IceCandidateNetworkType::kEthernet:
|
||||
return rtclog::IceCandidatePairConfig::ETHERNET;
|
||||
case IceCandidateNetworkType::kLoopback:
|
||||
return rtclog::IceCandidatePairConfig::LOOPBACK;
|
||||
case IceCandidateNetworkType::kWifi:
|
||||
return rtclog::IceCandidatePairConfig::WIFI;
|
||||
case IceCandidateNetworkType::kVpn:
|
||||
return rtclog::IceCandidatePairConfig::VPN;
|
||||
case IceCandidateNetworkType::kCellular:
|
||||
return rtclog::IceCandidatePairConfig::CELLULAR;
|
||||
case IceCandidateNetworkType::kNumValues:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
break;
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
|
||||
}
|
||||
|
||||
rtclog::IceCandidatePairEvent::IceCandidatePairEventType
|
||||
ConvertIceCandidatePairEventType(IceCandidatePairEventType type) {
|
||||
switch (type) {
|
||||
case IceCandidatePairEventType::kCheckSent:
|
||||
return rtclog::IceCandidatePairEvent::CHECK_SENT;
|
||||
case IceCandidatePairEventType::kCheckReceived:
|
||||
return rtclog::IceCandidatePairEvent::CHECK_RECEIVED;
|
||||
case IceCandidatePairEventType::kCheckResponseSent:
|
||||
return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT;
|
||||
case IceCandidatePairEventType::kCheckResponseReceived:
|
||||
return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED;
|
||||
case IceCandidatePairEventType::kNumValues:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return rtclog::IceCandidatePairEvent::CHECK_SENT;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(timestamp_us);
|
||||
rtclog_event.set_type(rtclog::Event::LOG_START);
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeLogEnd(int64_t timestamp_us) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(timestamp_us);
|
||||
rtclog_event.set_type(rtclog::Event::LOG_END);
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) {
|
||||
std::string encoded_output;
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
// TODO(terelius): Can we avoid the slight inefficiency of reallocating the
|
||||
// string?
|
||||
RTC_CHECK(it->get() != nullptr);
|
||||
encoded_output += Encode(**it);
|
||||
}
|
||||
return encoded_output;
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
|
||||
switch (event.GetType()) {
|
||||
case RtcEvent::Type::AudioNetworkAdaptation: {
|
||||
auto& rtc_event =
|
||||
static_cast<const RtcEventAudioNetworkAdaptation&>(event);
|
||||
return EncodeAudioNetworkAdaptation(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::AlrStateEvent: {
|
||||
auto& rtc_event = static_cast<const RtcEventAlrState&>(event);
|
||||
return EncodeAlrState(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::AudioPlayout: {
|
||||
auto& rtc_event = static_cast<const RtcEventAudioPlayout&>(event);
|
||||
return EncodeAudioPlayout(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::AudioReceiveStreamConfig: {
|
||||
auto& rtc_event =
|
||||
static_cast<const RtcEventAudioReceiveStreamConfig&>(event);
|
||||
return EncodeAudioReceiveStreamConfig(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::AudioSendStreamConfig: {
|
||||
auto& rtc_event =
|
||||
static_cast<const RtcEventAudioSendStreamConfig&>(event);
|
||||
return EncodeAudioSendStreamConfig(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::BweUpdateDelayBased: {
|
||||
auto& rtc_event = static_cast<const RtcEventBweUpdateDelayBased&>(event);
|
||||
return EncodeBweUpdateDelayBased(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::BweUpdateLossBased: {
|
||||
auto& rtc_event = static_cast<const RtcEventBweUpdateLossBased&>(event);
|
||||
return EncodeBweUpdateLossBased(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::DtlsTransportState: {
|
||||
return "";
|
||||
}
|
||||
|
||||
case RtcEvent::Type::DtlsWritableState: {
|
||||
return "";
|
||||
}
|
||||
|
||||
case RtcEvent::Type::IceCandidatePairConfig: {
|
||||
auto& rtc_event =
|
||||
static_cast<const RtcEventIceCandidatePairConfig&>(event);
|
||||
return EncodeIceCandidatePairConfig(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::IceCandidatePairEvent: {
|
||||
auto& rtc_event = static_cast<const RtcEventIceCandidatePair&>(event);
|
||||
return EncodeIceCandidatePairEvent(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::ProbeClusterCreated: {
|
||||
auto& rtc_event = static_cast<const RtcEventProbeClusterCreated&>(event);
|
||||
return EncodeProbeClusterCreated(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::ProbeResultFailure: {
|
||||
auto& rtc_event = static_cast<const RtcEventProbeResultFailure&>(event);
|
||||
return EncodeProbeResultFailure(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::ProbeResultSuccess: {
|
||||
auto& rtc_event = static_cast<const RtcEventProbeResultSuccess&>(event);
|
||||
return EncodeProbeResultSuccess(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::RemoteEstimateEvent: {
|
||||
auto& rtc_event = static_cast<const RtcEventRemoteEstimate&>(event);
|
||||
return EncodeRemoteEstimate(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::RtcpPacketIncoming: {
|
||||
auto& rtc_event = static_cast<const RtcEventRtcpPacketIncoming&>(event);
|
||||
return EncodeRtcpPacketIncoming(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::RtcpPacketOutgoing: {
|
||||
auto& rtc_event = static_cast<const RtcEventRtcpPacketOutgoing&>(event);
|
||||
return EncodeRtcpPacketOutgoing(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::RtpPacketIncoming: {
|
||||
auto& rtc_event = static_cast<const RtcEventRtpPacketIncoming&>(event);
|
||||
return EncodeRtpPacketIncoming(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::RtpPacketOutgoing: {
|
||||
auto& rtc_event = static_cast<const RtcEventRtpPacketOutgoing&>(event);
|
||||
return EncodeRtpPacketOutgoing(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::VideoReceiveStreamConfig: {
|
||||
auto& rtc_event =
|
||||
static_cast<const RtcEventVideoReceiveStreamConfig&>(event);
|
||||
return EncodeVideoReceiveStreamConfig(rtc_event);
|
||||
}
|
||||
|
||||
case RtcEvent::Type::VideoSendStreamConfig: {
|
||||
auto& rtc_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::FakeEvent:
|
||||
// Fake event used for unit test.
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
break;
|
||||
case RtcEvent::Type::RouteChangeEvent:
|
||||
case RtcEvent::Type::GenericPacketReceived:
|
||||
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 "";
|
||||
}
|
||||
|
||||
int event_type = static_cast<int>(event.GetType());
|
||||
RTC_DCHECK_NOTREACHED() << "Unknown event type (" << event_type << ")";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeAlrState(
|
||||
const RtcEventAlrState& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::ALR_STATE_EVENT);
|
||||
|
||||
auto* alr_state = rtclog_event.mutable_alr_state();
|
||||
alr_state->set_in_alr(event.in_alr());
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeAudioNetworkAdaptation(
|
||||
const RtcEventAudioNetworkAdaptation& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
|
||||
|
||||
auto* audio_network_adaptation =
|
||||
rtclog_event.mutable_audio_network_adaptation();
|
||||
if (event.config().bitrate_bps)
|
||||
audio_network_adaptation->set_bitrate_bps(*event.config().bitrate_bps);
|
||||
if (event.config().frame_length_ms)
|
||||
audio_network_adaptation->set_frame_length_ms(
|
||||
*event.config().frame_length_ms);
|
||||
if (event.config().uplink_packet_loss_fraction) {
|
||||
audio_network_adaptation->set_uplink_packet_loss_fraction(
|
||||
*event.config().uplink_packet_loss_fraction);
|
||||
}
|
||||
if (event.config().enable_fec)
|
||||
audio_network_adaptation->set_enable_fec(*event.config().enable_fec);
|
||||
if (event.config().enable_dtx)
|
||||
audio_network_adaptation->set_enable_dtx(*event.config().enable_dtx);
|
||||
if (event.config().num_channels)
|
||||
audio_network_adaptation->set_num_channels(*event.config().num_channels);
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeAudioPlayout(
|
||||
const RtcEventAudioPlayout& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
|
||||
|
||||
auto* playout_event = rtclog_event.mutable_audio_playout_event();
|
||||
playout_event->set_local_ssrc(event.ssrc());
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeAudioReceiveStreamConfig(
|
||||
const RtcEventAudioReceiveStreamConfig& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
|
||||
|
||||
rtclog::AudioReceiveConfig* receiver_config =
|
||||
rtclog_event.mutable_audio_receiver_config();
|
||||
receiver_config->set_remote_ssrc(event.config().remote_ssrc);
|
||||
receiver_config->set_local_ssrc(event.config().local_ssrc);
|
||||
|
||||
for (const auto& e : event.config().rtp_extensions) {
|
||||
rtclog::RtpHeaderExtension* extension =
|
||||
receiver_config->add_header_extensions();
|
||||
extension->set_name(e.uri);
|
||||
extension->set_id(e.id);
|
||||
}
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeAudioSendStreamConfig(
|
||||
const RtcEventAudioSendStreamConfig& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
|
||||
|
||||
rtclog::AudioSendConfig* sender_config =
|
||||
rtclog_event.mutable_audio_sender_config();
|
||||
|
||||
sender_config->set_ssrc(event.config().local_ssrc);
|
||||
|
||||
for (const auto& e : event.config().rtp_extensions) {
|
||||
rtclog::RtpHeaderExtension* extension =
|
||||
sender_config->add_header_extensions();
|
||||
extension->set_name(e.uri);
|
||||
extension->set_id(e.id);
|
||||
}
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeBweUpdateDelayBased(
|
||||
const RtcEventBweUpdateDelayBased& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::DELAY_BASED_BWE_UPDATE);
|
||||
|
||||
auto* bwe_event = rtclog_event.mutable_delay_based_bwe_update();
|
||||
bwe_event->set_bitrate_bps(event.bitrate_bps());
|
||||
bwe_event->set_detector_state(ConvertDetectorState(event.detector_state()));
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased(
|
||||
const RtcEventBweUpdateLossBased& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::LOSS_BASED_BWE_UPDATE);
|
||||
|
||||
auto* bwe_event = rtclog_event.mutable_loss_based_bwe_update();
|
||||
bwe_event->set_bitrate_bps(event.bitrate_bps());
|
||||
bwe_event->set_fraction_loss(event.fraction_loss());
|
||||
bwe_event->set_total_packets(event.total_packets());
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairConfig(
|
||||
const RtcEventIceCandidatePairConfig& event) {
|
||||
rtclog::Event encoded_rtc_event;
|
||||
encoded_rtc_event.set_timestamp_us(event.timestamp_us());
|
||||
encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
|
||||
|
||||
auto* encoded_ice_event =
|
||||
encoded_rtc_event.mutable_ice_candidate_pair_config();
|
||||
encoded_ice_event->set_config_type(
|
||||
ConvertIceCandidatePairConfigType(event.type()));
|
||||
encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
|
||||
const auto& desc = event.candidate_pair_desc();
|
||||
encoded_ice_event->set_local_candidate_type(
|
||||
ConvertIceCandidateType(desc.local_candidate_type));
|
||||
encoded_ice_event->set_local_relay_protocol(
|
||||
ConvertIceCandidatePairProtocol(desc.local_relay_protocol));
|
||||
encoded_ice_event->set_local_network_type(
|
||||
ConvertIceCandidateNetworkType(desc.local_network_type));
|
||||
encoded_ice_event->set_local_address_family(
|
||||
ConvertIceCandidatePairAddressFamily(desc.local_address_family));
|
||||
encoded_ice_event->set_remote_candidate_type(
|
||||
ConvertIceCandidateType(desc.remote_candidate_type));
|
||||
encoded_ice_event->set_remote_address_family(
|
||||
ConvertIceCandidatePairAddressFamily(desc.remote_address_family));
|
||||
encoded_ice_event->set_candidate_pair_protocol(
|
||||
ConvertIceCandidatePairProtocol(desc.candidate_pair_protocol));
|
||||
return Serialize(&encoded_rtc_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairEvent(
|
||||
const RtcEventIceCandidatePair& event) {
|
||||
rtclog::Event encoded_rtc_event;
|
||||
encoded_rtc_event.set_timestamp_us(event.timestamp_us());
|
||||
encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
|
||||
|
||||
auto* encoded_ice_event =
|
||||
encoded_rtc_event.mutable_ice_candidate_pair_event();
|
||||
encoded_ice_event->set_event_type(
|
||||
ConvertIceCandidatePairEventType(event.type()));
|
||||
encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
|
||||
return Serialize(&encoded_rtc_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
|
||||
const RtcEventProbeClusterCreated& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
|
||||
|
||||
auto* probe_cluster = rtclog_event.mutable_probe_cluster();
|
||||
probe_cluster->set_id(event.id());
|
||||
probe_cluster->set_bitrate_bps(event.bitrate_bps());
|
||||
probe_cluster->set_min_packets(event.min_probes());
|
||||
probe_cluster->set_min_bytes(event.min_bytes());
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeProbeResultFailure(
|
||||
const RtcEventProbeResultFailure& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
|
||||
|
||||
auto* probe_result = rtclog_event.mutable_probe_result();
|
||||
probe_result->set_id(event.id());
|
||||
probe_result->set_result(ConvertProbeResultType(event.failure_reason()));
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeProbeResultSuccess(
|
||||
const RtcEventProbeResultSuccess& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
|
||||
|
||||
auto* probe_result = rtclog_event.mutable_probe_result();
|
||||
probe_result->set_id(event.id());
|
||||
probe_result->set_result(rtclog::BweProbeResult::SUCCESS);
|
||||
probe_result->set_bitrate_bps(event.bitrate_bps());
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRemoteEstimate(
|
||||
const RtcEventRemoteEstimate& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::REMOTE_ESTIMATE);
|
||||
|
||||
auto* remote_estimate = rtclog_event.mutable_remote_estimate();
|
||||
if (event.link_capacity_lower_.IsFinite())
|
||||
remote_estimate->set_link_capacity_lower_kbps(
|
||||
event.link_capacity_lower_.kbps<uint32_t>());
|
||||
if (event.link_capacity_upper_.IsFinite())
|
||||
remote_estimate->set_link_capacity_upper_kbps(
|
||||
event.link_capacity_upper_.kbps<uint32_t>());
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming(
|
||||
const RtcEventRtcpPacketIncoming& event) {
|
||||
return EncodeRtcpPacket(event.timestamp_us(), event.packet(), true);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketOutgoing(
|
||||
const RtcEventRtcpPacketOutgoing& event) {
|
||||
return EncodeRtcpPacket(event.timestamp_us(), event.packet(), false);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtpPacketIncoming(
|
||||
const RtcEventRtpPacketIncoming& event) {
|
||||
return EncodeRtpPacket(event.timestamp_us(), event.RawHeader(),
|
||||
event.packet_length(), PacedPacketInfo::kNotAProbe,
|
||||
true);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtpPacketOutgoing(
|
||||
const RtcEventRtpPacketOutgoing& event) {
|
||||
return EncodeRtpPacket(event.timestamp_us(), event.RawHeader(),
|
||||
event.packet_length(), event.probe_cluster_id(),
|
||||
false);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeVideoReceiveStreamConfig(
|
||||
const RtcEventVideoReceiveStreamConfig& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
|
||||
|
||||
rtclog::VideoReceiveConfig* receiver_config =
|
||||
rtclog_event.mutable_video_receiver_config();
|
||||
receiver_config->set_remote_ssrc(event.config().remote_ssrc);
|
||||
receiver_config->set_local_ssrc(event.config().local_ssrc);
|
||||
|
||||
// TODO(perkj): Add field for rsid.
|
||||
receiver_config->set_rtcp_mode(ConvertRtcpMode(event.config().rtcp_mode));
|
||||
receiver_config->set_remb(event.config().remb);
|
||||
|
||||
for (const auto& e : event.config().rtp_extensions) {
|
||||
rtclog::RtpHeaderExtension* extension =
|
||||
receiver_config->add_header_extensions();
|
||||
extension->set_name(e.uri);
|
||||
extension->set_id(e.id);
|
||||
}
|
||||
|
||||
for (const auto& d : event.config().codecs) {
|
||||
rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
|
||||
decoder->set_name(d.payload_name);
|
||||
decoder->set_payload_type(d.payload_type);
|
||||
if (d.rtx_payload_type != 0) {
|
||||
rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
|
||||
rtx->set_payload_type(d.payload_type);
|
||||
rtx->mutable_config()->set_rtx_ssrc(event.config().rtx_ssrc);
|
||||
rtx->mutable_config()->set_rtx_payload_type(d.rtx_payload_type);
|
||||
}
|
||||
}
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeVideoSendStreamConfig(
|
||||
const RtcEventVideoSendStreamConfig& event) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(event.timestamp_us());
|
||||
rtclog_event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
|
||||
|
||||
rtclog::VideoSendConfig* sender_config =
|
||||
rtclog_event.mutable_video_sender_config();
|
||||
|
||||
// TODO(perkj): rtclog::VideoSendConfig should only contain one SSRC.
|
||||
sender_config->add_ssrcs(event.config().local_ssrc);
|
||||
if (event.config().rtx_ssrc != 0) {
|
||||
sender_config->add_rtx_ssrcs(event.config().rtx_ssrc);
|
||||
}
|
||||
|
||||
for (const auto& e : event.config().rtp_extensions) {
|
||||
rtclog::RtpHeaderExtension* extension =
|
||||
sender_config->add_header_extensions();
|
||||
extension->set_name(e.uri);
|
||||
extension->set_id(e.id);
|
||||
}
|
||||
|
||||
// TODO(perkj): rtclog::VideoSendConfig should contain many possible codec
|
||||
// configurations.
|
||||
for (const auto& codec : event.config().codecs) {
|
||||
sender_config->set_rtx_payload_type(codec.rtx_payload_type);
|
||||
rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
|
||||
encoder->set_name(codec.payload_name);
|
||||
encoder->set_payload_type(codec.payload_type);
|
||||
|
||||
if (event.config().codecs.size() > 1) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "LogVideoSendStreamConfig currently only supports one "
|
||||
"codec. Logging codec :"
|
||||
<< codec.payload_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket(
|
||||
int64_t timestamp_us,
|
||||
const rtc::Buffer& packet,
|
||||
bool is_incoming) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(timestamp_us);
|
||||
rtclog_event.set_type(rtclog::Event::RTCP_EVENT);
|
||||
rtclog_event.mutable_rtcp_packet()->set_incoming(is_incoming);
|
||||
|
||||
rtcp::CommonHeader header;
|
||||
const uint8_t* block_begin = packet.data();
|
||||
const uint8_t* packet_end = packet.data() + packet.size();
|
||||
std::vector<uint8_t> buffer(packet.size());
|
||||
uint32_t buffer_length = 0;
|
||||
while (block_begin < packet_end) {
|
||||
if (!header.Parse(block_begin, packet_end - block_begin)) {
|
||||
break; // Incorrect message header.
|
||||
}
|
||||
const uint8_t* next_block = header.NextPacket();
|
||||
uint32_t block_size = next_block - block_begin;
|
||||
switch (header.type()) {
|
||||
case rtcp::Bye::kPacketType:
|
||||
case rtcp::ExtendedReports::kPacketType:
|
||||
case rtcp::Psfb::kPacketType:
|
||||
case rtcp::ReceiverReport::kPacketType:
|
||||
case rtcp::Rtpfb::kPacketType:
|
||||
case rtcp::SenderReport::kPacketType:
|
||||
// We log sender reports, receiver reports, bye messages, third-party
|
||||
// loss reports, payload-specific feedback and extended reports.
|
||||
memcpy(buffer.data() + buffer_length, block_begin, block_size);
|
||||
buffer_length += block_size;
|
||||
break;
|
||||
case rtcp::App::kPacketType:
|
||||
case rtcp::Sdes::kPacketType:
|
||||
default:
|
||||
// We don't log sender descriptions, application defined messages
|
||||
// or message blocks of unknown type.
|
||||
break;
|
||||
}
|
||||
|
||||
block_begin += block_size;
|
||||
}
|
||||
rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer.data(),
|
||||
buffer_length);
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::EncodeRtpPacket(
|
||||
int64_t timestamp_us,
|
||||
rtc::ArrayView<const uint8_t> header,
|
||||
size_t packet_length,
|
||||
int probe_cluster_id,
|
||||
bool is_incoming) {
|
||||
rtclog::Event rtclog_event;
|
||||
rtclog_event.set_timestamp_us(timestamp_us);
|
||||
rtclog_event.set_type(rtclog::Event::RTP_EVENT);
|
||||
|
||||
rtclog_event.mutable_rtp_packet()->set_incoming(is_incoming);
|
||||
rtclog_event.mutable_rtp_packet()->set_packet_length(packet_length);
|
||||
rtclog_event.mutable_rtp_packet()->set_header(header.data(), header.size());
|
||||
if (probe_cluster_id != PacedPacketInfo::kNotAProbe) {
|
||||
RTC_DCHECK(!is_incoming);
|
||||
rtclog_event.mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id);
|
||||
}
|
||||
|
||||
return Serialize(&rtclog_event);
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderLegacy::Serialize(rtclog::Event* event) {
|
||||
// Even though we're only serializing a single event during this call, what
|
||||
// we intend to get is a list of events, with a tag and length preceding
|
||||
// each actual event. To produce that, we serialize a list of a single event.
|
||||
// If we later concatenate several results from this function, the result will
|
||||
// be a proper concatenation of all those events.
|
||||
|
||||
rtclog::EventStream event_stream;
|
||||
event_stream.add_stream();
|
||||
|
||||
// As a tweak, we swap the new event into the event-stream, write that to
|
||||
// file, then swap back. This saves on some copying, while making sure that
|
||||
// the caller wouldn't be surprised by Serialize() modifying the object.
|
||||
rtclog::Event* output_event = event_stream.mutable_stream(0);
|
||||
output_event->Swap(event);
|
||||
|
||||
std::string output_string = event_stream.SerializeAsString();
|
||||
RTC_DCHECK(!output_string.empty());
|
||||
|
||||
// When the function returns, the original Event will be unchanged.
|
||||
output_event->Swap(event);
|
||||
|
||||
return output_string;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace rtclog {
|
||||
class Event; // Auto-generated from protobuf.
|
||||
} // namespace rtclog
|
||||
|
||||
class RtcEventAlrState;
|
||||
class RtcEventAudioNetworkAdaptation;
|
||||
class RtcEventAudioPlayout;
|
||||
class RtcEventAudioReceiveStreamConfig;
|
||||
class RtcEventAudioSendStreamConfig;
|
||||
class RtcEventBweUpdateDelayBased;
|
||||
class RtcEventBweUpdateLossBased;
|
||||
class RtcEventIceCandidatePairConfig;
|
||||
class RtcEventIceCandidatePair;
|
||||
class RtcEventLoggingStarted;
|
||||
class RtcEventLoggingStopped;
|
||||
class RtcEventProbeClusterCreated;
|
||||
class RtcEventProbeResultFailure;
|
||||
class RtcEventProbeResultSuccess;
|
||||
class RtcEventRemoteEstimate;
|
||||
class RtcEventRtcpPacketIncoming;
|
||||
class RtcEventRtcpPacketOutgoing;
|
||||
class RtcEventRtpPacketIncoming;
|
||||
class RtcEventRtpPacketOutgoing;
|
||||
class RtcEventVideoReceiveStreamConfig;
|
||||
class RtcEventVideoSendStreamConfig;
|
||||
class RtpPacket;
|
||||
|
||||
class RtcEventLogEncoderLegacy final : public RtcEventLogEncoder {
|
||||
public:
|
||||
~RtcEventLogEncoderLegacy() override = default;
|
||||
|
||||
std::string EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) override;
|
||||
std::string EncodeLogEnd(int64_t timestamp_us) override;
|
||||
|
||||
std::string EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) override;
|
||||
|
||||
private:
|
||||
std::string Encode(const RtcEvent& event);
|
||||
// Encoding entry-point for the various RtcEvent subclasses.
|
||||
std::string EncodeAlrState(const RtcEventAlrState& event);
|
||||
std::string EncodeAudioNetworkAdaptation(
|
||||
const RtcEventAudioNetworkAdaptation& event);
|
||||
std::string EncodeAudioPlayout(const RtcEventAudioPlayout& event);
|
||||
std::string EncodeAudioReceiveStreamConfig(
|
||||
const RtcEventAudioReceiveStreamConfig& event);
|
||||
std::string EncodeAudioSendStreamConfig(
|
||||
const RtcEventAudioSendStreamConfig& event);
|
||||
std::string EncodeBweUpdateDelayBased(
|
||||
const RtcEventBweUpdateDelayBased& event);
|
||||
std::string EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased& event);
|
||||
std::string EncodeIceCandidatePairConfig(
|
||||
const RtcEventIceCandidatePairConfig& event);
|
||||
std::string EncodeIceCandidatePairEvent(
|
||||
const RtcEventIceCandidatePair& event);
|
||||
std::string EncodeProbeClusterCreated(
|
||||
const RtcEventProbeClusterCreated& event);
|
||||
std::string EncodeProbeResultFailure(const RtcEventProbeResultFailure& event);
|
||||
std::string EncodeProbeResultSuccess(const RtcEventProbeResultSuccess&);
|
||||
std::string EncodeRemoteEstimate(const RtcEventRemoteEstimate& event);
|
||||
std::string EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming& event);
|
||||
std::string EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing& event);
|
||||
std::string EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming& event);
|
||||
std::string EncodeRtpPacketOutgoing(const RtcEventRtpPacketOutgoing& event);
|
||||
std::string EncodeVideoReceiveStreamConfig(
|
||||
const RtcEventVideoReceiveStreamConfig& event);
|
||||
std::string EncodeVideoSendStreamConfig(
|
||||
const RtcEventVideoSendStreamConfig& event);
|
||||
|
||||
// RTCP/RTP are handled similarly for incoming/outgoing.
|
||||
std::string EncodeRtcpPacket(int64_t timestamp_us,
|
||||
const rtc::Buffer& packet,
|
||||
bool is_incoming);
|
||||
std::string EncodeRtpPacket(int64_t timestamp_us,
|
||||
rtc::ArrayView<const uint8_t> header,
|
||||
size_t packet_length,
|
||||
int probe_cluster_id,
|
||||
bool is_incoming);
|
||||
|
||||
std::string Serialize(rtclog::Event* event);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ENCODER_RTC_EVENT_LOG_ENCODER_NEW_FORMAT_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_NEW_FORMAT_H_
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace rtclog2 {
|
||||
class EventStream; // Auto-generated from protobuf.
|
||||
} // namespace rtclog2
|
||||
|
||||
class RtcEventAlrState;
|
||||
class RtcEventRouteChange;
|
||||
class RtcEventRemoteEstimate;
|
||||
class RtcEventAudioNetworkAdaptation;
|
||||
class RtcEventAudioPlayout;
|
||||
class RtcEventAudioReceiveStreamConfig;
|
||||
class RtcEventAudioSendStreamConfig;
|
||||
class RtcEventBweUpdateDelayBased;
|
||||
class RtcEventBweUpdateLossBased;
|
||||
class RtcEventDtlsTransportState;
|
||||
class RtcEventDtlsWritableState;
|
||||
class RtcEventLoggingStarted;
|
||||
class RtcEventLoggingStopped;
|
||||
class RtcEventNetEqSetMinimumDelay;
|
||||
class RtcEventProbeClusterCreated;
|
||||
class RtcEventProbeResultFailure;
|
||||
class RtcEventProbeResultSuccess;
|
||||
class RtcEventRtcpPacketIncoming;
|
||||
class RtcEventRtcpPacketOutgoing;
|
||||
class RtcEventRtpPacketIncoming;
|
||||
class RtcEventRtpPacketOutgoing;
|
||||
class RtcEventVideoReceiveStreamConfig;
|
||||
class RtcEventVideoSendStreamConfig;
|
||||
class RtcEventIceCandidatePairConfig;
|
||||
class RtcEventIceCandidatePair;
|
||||
class RtpPacket;
|
||||
class RtcEventFrameDecoded;
|
||||
class RtcEventGenericAckReceived;
|
||||
class RtcEventGenericPacketReceived;
|
||||
class RtcEventGenericPacketSent;
|
||||
|
||||
class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
|
||||
public:
|
||||
explicit RtcEventLogEncoderNewFormat(const FieldTrialsView& field_trials);
|
||||
~RtcEventLogEncoderNewFormat() override = default;
|
||||
|
||||
std::string EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) override;
|
||||
|
||||
std::string EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) override;
|
||||
std::string EncodeLogEnd(int64_t timestamp_us) override;
|
||||
|
||||
private:
|
||||
// Encoding entry-point for the various RtcEvent subclasses.
|
||||
void EncodeAlrState(rtc::ArrayView<const RtcEventAlrState*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeAudioNetworkAdaptation(
|
||||
rtc::ArrayView<const RtcEventAudioNetworkAdaptation*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeAudioPlayout(rtc::ArrayView<const RtcEventAudioPlayout*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeAudioRecvStreamConfig(
|
||||
rtc::ArrayView<const RtcEventAudioReceiveStreamConfig*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeAudioSendStreamConfig(
|
||||
rtc::ArrayView<const RtcEventAudioSendStreamConfig*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeBweUpdateDelayBased(
|
||||
rtc::ArrayView<const RtcEventBweUpdateDelayBased*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeBweUpdateLossBased(
|
||||
rtc::ArrayView<const RtcEventBweUpdateLossBased*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeDtlsTransportState(
|
||||
rtc::ArrayView<const RtcEventDtlsTransportState*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeDtlsWritableState(
|
||||
rtc::ArrayView<const RtcEventDtlsWritableState*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeFramesDecoded(
|
||||
rtc::ArrayView<const RtcEventFrameDecoded* const> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeGenericAcksReceived(
|
||||
rtc::ArrayView<const RtcEventGenericAckReceived*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeGenericPacketsReceived(
|
||||
rtc::ArrayView<const RtcEventGenericPacketReceived*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeGenericPacketsSent(
|
||||
rtc::ArrayView<const RtcEventGenericPacketSent*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeIceCandidatePairConfig(
|
||||
rtc::ArrayView<const RtcEventIceCandidatePairConfig*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeIceCandidatePairEvent(
|
||||
rtc::ArrayView<const RtcEventIceCandidatePair*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeLoggingStarted(rtc::ArrayView<const RtcEventLoggingStarted*> batch,
|
||||
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);
|
||||
void EncodeProbeResultFailure(
|
||||
rtc::ArrayView<const RtcEventProbeResultFailure*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeProbeResultSuccess(
|
||||
rtc::ArrayView<const RtcEventProbeResultSuccess*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRouteChange(rtc::ArrayView<const RtcEventRouteChange*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRemoteEstimate(rtc::ArrayView<const RtcEventRemoteEstimate*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRtcpPacketIncoming(
|
||||
rtc::ArrayView<const RtcEventRtcpPacketIncoming*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRtcpPacketOutgoing(
|
||||
rtc::ArrayView<const RtcEventRtcpPacketOutgoing*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRtpPacketIncoming(
|
||||
const std::map<uint32_t, std::vector<const RtcEventRtpPacketIncoming*>>&
|
||||
batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeRtpPacketOutgoing(
|
||||
const std::map<uint32_t, std::vector<const RtcEventRtpPacketOutgoing*>>&
|
||||
batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeVideoRecvStreamConfig(
|
||||
rtc::ArrayView<const RtcEventVideoReceiveStreamConfig*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
void EncodeVideoSendStreamConfig(
|
||||
rtc::ArrayView<const RtcEventVideoSendStreamConfig*> batch,
|
||||
rtclog2::EventStream* event_stream);
|
||||
template <typename Batch, typename ProtoType>
|
||||
void EncodeRtpPacket(const Batch& batch, ProtoType* proto_batch);
|
||||
|
||||
const bool encode_neteq_set_minimum_delay_kill_switch_;
|
||||
const bool encode_dependency_descriptor_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_NEW_FORMAT_H_
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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/encoder/rtc_event_log_encoder_v3.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
|
||||
#include "logging/rtc_event_log/encoder/var_int.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
|
||||
#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"
|
||||
#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_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"
|
||||
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_route_change.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string RtcEventLogEncoderV3::EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) {
|
||||
std::unique_ptr<RtcEventBeginLog> begin_log =
|
||||
std::make_unique<RtcEventBeginLog>(Timestamp::Micros(timestamp_us),
|
||||
Timestamp::Micros(utc_time_us));
|
||||
std::vector<const RtcEvent*> batch;
|
||||
batch.push_back(begin_log.get());
|
||||
|
||||
std::string encoded_event = RtcEventBeginLog::Encode(batch);
|
||||
|
||||
return encoded_event;
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderV3::EncodeLogEnd(int64_t timestamp_us) {
|
||||
std::unique_ptr<RtcEventEndLog> end_log =
|
||||
std::make_unique<RtcEventEndLog>(Timestamp::Micros(timestamp_us));
|
||||
std::vector<const RtcEvent*> batch;
|
||||
batch.push_back(end_log.get());
|
||||
|
||||
std::string encoded_event = RtcEventEndLog::Encode(batch);
|
||||
|
||||
return encoded_event;
|
||||
}
|
||||
|
||||
RtcEventLogEncoderV3::RtcEventLogEncoderV3() {
|
||||
encoders_[RtcEvent::Type::AlrStateEvent] = RtcEventAlrState::Encode;
|
||||
encoders_[RtcEvent::Type::AudioNetworkAdaptation] =
|
||||
RtcEventAudioNetworkAdaptation::Encode;
|
||||
encoders_[RtcEvent::Type::AudioPlayout] = RtcEventAudioPlayout::Encode;
|
||||
encoders_[RtcEvent::Type::AudioReceiveStreamConfig] =
|
||||
RtcEventAudioReceiveStreamConfig::Encode;
|
||||
encoders_[RtcEvent::Type::AudioSendStreamConfig] =
|
||||
RtcEventAudioSendStreamConfig::Encode;
|
||||
encoders_[RtcEvent::Type::BweUpdateDelayBased] =
|
||||
RtcEventBweUpdateDelayBased::Encode;
|
||||
encoders_[RtcEvent::Type::BweUpdateLossBased] =
|
||||
RtcEventBweUpdateLossBased::Encode;
|
||||
encoders_[RtcEvent::Type::DtlsTransportState] =
|
||||
RtcEventDtlsTransportState::Encode;
|
||||
encoders_[RtcEvent::Type::DtlsWritableState] =
|
||||
RtcEventDtlsWritableState::Encode;
|
||||
encoders_[RtcEvent::Type::FrameDecoded] = RtcEventFrameDecoded::Encode;
|
||||
encoders_[RtcEvent::Type::GenericAckReceived] =
|
||||
RtcEventGenericAckReceived::Encode;
|
||||
encoders_[RtcEvent::Type::GenericPacketReceived] =
|
||||
RtcEventGenericPacketReceived::Encode;
|
||||
encoders_[RtcEvent::Type::GenericPacketSent] =
|
||||
RtcEventGenericPacketSent::Encode;
|
||||
encoders_[RtcEvent::Type::IceCandidatePairConfig] =
|
||||
RtcEventIceCandidatePairConfig::Encode;
|
||||
encoders_[RtcEvent::Type::IceCandidatePairEvent] =
|
||||
RtcEventIceCandidatePair::Encode;
|
||||
encoders_[RtcEvent::Type::ProbeClusterCreated] =
|
||||
RtcEventProbeClusterCreated::Encode;
|
||||
encoders_[RtcEvent::Type::ProbeResultFailure] =
|
||||
RtcEventProbeResultFailure::Encode;
|
||||
encoders_[RtcEvent::Type::ProbeResultSuccess] =
|
||||
RtcEventProbeResultSuccess::Encode;
|
||||
encoders_[RtcEvent::Type::RemoteEstimateEvent] =
|
||||
RtcEventRemoteEstimate::Encode;
|
||||
encoders_[RtcEvent::Type::RouteChangeEvent] = RtcEventRouteChange::Encode;
|
||||
encoders_[RtcEvent::Type::RtcpPacketIncoming] =
|
||||
RtcEventRtcpPacketIncoming::Encode;
|
||||
encoders_[RtcEvent::Type::RtcpPacketOutgoing] =
|
||||
RtcEventRtcpPacketOutgoing::Encode;
|
||||
encoders_[RtcEvent::Type::RtpPacketIncoming] =
|
||||
RtcEventRtpPacketIncoming::Encode;
|
||||
encoders_[RtcEvent::Type::RtpPacketOutgoing] =
|
||||
RtcEventRtpPacketOutgoing::Encode;
|
||||
encoders_[RtcEvent::Type::VideoReceiveStreamConfig] =
|
||||
RtcEventVideoReceiveStreamConfig::Encode;
|
||||
encoders_[RtcEvent::Type::VideoSendStreamConfig] =
|
||||
RtcEventVideoSendStreamConfig::Encode;
|
||||
}
|
||||
|
||||
std::string RtcEventLogEncoderV3::EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) {
|
||||
struct EventGroupKey {
|
||||
// Events are grouped by event type. For compression efficiency,
|
||||
// events can optionally have a secondary key, in most cases the
|
||||
// SSRC.
|
||||
RtcEvent::Type type;
|
||||
uint32_t secondary_group_key;
|
||||
|
||||
bool operator<(EventGroupKey other) const {
|
||||
return type < other.type ||
|
||||
(type == other.type &&
|
||||
secondary_group_key < other.secondary_group_key);
|
||||
}
|
||||
};
|
||||
|
||||
std::map<EventGroupKey, std::vector<const RtcEvent*>> event_groups;
|
||||
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
event_groups[{(*it)->GetType(), (*it)->GetGroupKey()}].push_back(it->get());
|
||||
}
|
||||
|
||||
std::string encoded_output;
|
||||
for (auto& kv : event_groups) {
|
||||
auto it = encoders_.find(kv.first.type);
|
||||
RTC_DCHECK(it != encoders_.end());
|
||||
if (it != encoders_.end()) {
|
||||
auto& encoder = it->second;
|
||||
// TODO(terelius): Use some "string builder" or preallocate?
|
||||
encoded_output += encoder(kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
return encoded_output;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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_ENCODER_RTC_EVENT_LOG_ENCODER_V3_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_V3_H_
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_definition.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtcEventLogEncoderV3 final : public RtcEventLogEncoder {
|
||||
public:
|
||||
RtcEventLogEncoderV3();
|
||||
~RtcEventLogEncoderV3() override = default;
|
||||
|
||||
std::string EncodeBatch(
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
|
||||
std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) override;
|
||||
|
||||
std::string EncodeLogStart(int64_t timestamp_us,
|
||||
int64_t utc_time_us) override;
|
||||
std::string EncodeLogEnd(int64_t timestamp_us) override;
|
||||
|
||||
private:
|
||||
std::map<RtcEvent::Type,
|
||||
std::function<std::string(rtc::ArrayView<const RtcEvent*>)>>
|
||||
encoders_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_V3_H_
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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/encoder/var_int.h"
|
||||
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
// TODO(eladalon): Add unit tests.
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const size_t kMaxVarIntLengthBytes = 10; // ceil(64 / 7.0) is 10.
|
||||
|
||||
std::string EncodeVarInt(uint64_t input) {
|
||||
std::string output;
|
||||
output.reserve(kMaxVarIntLengthBytes);
|
||||
|
||||
do {
|
||||
uint8_t byte = static_cast<uint8_t>(input & 0x7f);
|
||||
input >>= 7;
|
||||
if (input > 0) {
|
||||
byte |= 0x80;
|
||||
}
|
||||
output += byte;
|
||||
} while (input > 0);
|
||||
|
||||
RTC_DCHECK_GE(output.size(), 1u);
|
||||
RTC_DCHECK_LE(output.size(), kMaxVarIntLengthBytes);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// There is some code duplication between the flavors of this function.
|
||||
// For performance's sake, it's best to just keep it.
|
||||
std::pair<bool, absl::string_view> DecodeVarInt(absl::string_view input,
|
||||
uint64_t* output) {
|
||||
RTC_DCHECK(output);
|
||||
|
||||
uint64_t decoded = 0;
|
||||
for (size_t i = 0; i < input.length() && i < kMaxVarIntLengthBytes; ++i) {
|
||||
decoded += (static_cast<uint64_t>(input[i] & 0x7f)
|
||||
<< static_cast<uint64_t>(7 * i));
|
||||
if (!(input[i] & 0x80)) {
|
||||
*output = decoded;
|
||||
return {true, input.substr(i + 1)};
|
||||
}
|
||||
}
|
||||
|
||||
return {false, input};
|
||||
}
|
||||
|
||||
// There is some code duplication between the flavors of this function.
|
||||
// For performance's sake, it's best to just keep it.
|
||||
uint64_t DecodeVarInt(BitstreamReader& input) {
|
||||
uint64_t decoded = 0;
|
||||
for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) {
|
||||
uint8_t byte = input.Read<uint8_t>();
|
||||
decoded +=
|
||||
(static_cast<uint64_t>(byte & 0x7f) << static_cast<uint64_t>(7 * i));
|
||||
if (!(byte & 0x80)) {
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
|
||||
input.Invalidate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_ENCODER_VAR_INT_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ENCODER_VAR_INT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
extern const size_t kMaxVarIntLengthBytes;
|
||||
|
||||
// Encode a given uint64_t as a varint. From least to most significant,
|
||||
// each batch of seven bits are put into the lower bits of a byte, and the last
|
||||
// remaining bit in that byte (the highest one) marks whether additional bytes
|
||||
// follow (which happens if and only if there are other bits in `input` which
|
||||
// are non-zero).
|
||||
// Notes: If input == 0, one byte is used. If input is uint64_t::max, exactly
|
||||
// kMaxVarIntLengthBytes are used.
|
||||
std::string EncodeVarInt(uint64_t input);
|
||||
|
||||
// Inverse of EncodeVarInt().
|
||||
// Returns true and the remaining (unread) slice of the input if decoding
|
||||
// succeeds. Returns false otherwise and `output` is not modified.
|
||||
std::pair<bool, absl::string_view> DecodeVarInt(absl::string_view input,
|
||||
uint64_t* output);
|
||||
|
||||
// Same as other version, but uses a BitstreamReader for input.
|
||||
// If decoding is successful returns the decoded varint.
|
||||
// If not successful, `input` reader is set into the failure state, return value
|
||||
// is unspecified.
|
||||
uint64_t DecodeVarInt(BitstreamReader& input);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ENCODER_VAR_INT_H_
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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/fixed_length_encoding_parameters_v3.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
using webrtc_event_logging::MaxUnsignedValueOfBitWidth;
|
||||
using webrtc_event_logging::SignedBitWidth;
|
||||
using webrtc_event_logging::UnsignedBitWidth;
|
||||
using webrtc_event_logging::UnsignedDelta;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
FixedLengthEncodingParametersV3
|
||||
FixedLengthEncodingParametersV3::CalculateParameters(
|
||||
uint64_t base,
|
||||
const rtc::ArrayView<const uint64_t> values,
|
||||
uint64_t value_bit_width,
|
||||
bool values_optional) {
|
||||
// As a special case, if all of the elements are identical to the base
|
||||
// we just encode the base value with a special delta header.
|
||||
if (std::all_of(values.cbegin(), values.cend(),
|
||||
[base](uint64_t val) { return val == base; })) {
|
||||
// Delta header with signed=true and delta_bitwidth=64
|
||||
return FixedLengthEncodingParametersV3(/*delta_bit_width=*/64,
|
||||
/*signed_deltas=*/true,
|
||||
values_optional, value_bit_width);
|
||||
}
|
||||
|
||||
const uint64_t bit_mask = MaxUnsignedValueOfBitWidth(value_bit_width);
|
||||
|
||||
// Calculate the bitwidth required to encode all deltas when using a
|
||||
// unsigned or signed represenation, respectively. For the unsigned
|
||||
// representation, we just track the largest delta. For the signed
|
||||
// representation, we have two possibilities for each delta; either
|
||||
// going "forward" (i.e. current - previous) or "backwards"
|
||||
// (i.e. previous - current) where both values are calculated with
|
||||
// wrap around. We then track the largest positive and negative
|
||||
// magnitude across the batch, assuming that we choose the smaller
|
||||
// delta for each element.
|
||||
uint64_t max_unsigned_delta = 0;
|
||||
uint64_t max_positive_signed_delta = 0;
|
||||
uint64_t min_negative_signed_delta = 0;
|
||||
uint64_t prev = base;
|
||||
for (uint64_t current : values) {
|
||||
uint64_t positive_delta = UnsignedDelta(prev, current, bit_mask);
|
||||
uint64_t negative_delta = UnsignedDelta(current, prev, bit_mask);
|
||||
|
||||
max_unsigned_delta = std::max(max_unsigned_delta, positive_delta);
|
||||
|
||||
if (positive_delta < negative_delta) {
|
||||
max_positive_signed_delta =
|
||||
std::max(max_positive_signed_delta, positive_delta);
|
||||
} else {
|
||||
min_negative_signed_delta =
|
||||
std::max(min_negative_signed_delta, negative_delta);
|
||||
}
|
||||
|
||||
prev = current;
|
||||
}
|
||||
|
||||
// We now know the largest unsigned delta and the largest magnitudes of
|
||||
// positive and negative signed deltas. Get the bitwidths required for
|
||||
// each of the two encodings.
|
||||
const uint64_t unsigned_delta_bit_width =
|
||||
UnsignedBitWidth(max_unsigned_delta);
|
||||
const uint64_t signed_delta_bit_width =
|
||||
SignedBitWidth(max_positive_signed_delta, min_negative_signed_delta);
|
||||
|
||||
// Note: Preference for unsigned if the two have the same width (efficiency).
|
||||
bool use_signed_deltas = signed_delta_bit_width < unsigned_delta_bit_width;
|
||||
uint64_t delta_bit_width =
|
||||
use_signed_deltas ? signed_delta_bit_width : unsigned_delta_bit_width;
|
||||
|
||||
// use_signed_deltas && delta_bit_width==64 is reserved for "all values
|
||||
// equal".
|
||||
RTC_DCHECK(!use_signed_deltas || delta_bit_width < 64);
|
||||
|
||||
RTC_DCHECK(ValidParameters(delta_bit_width, use_signed_deltas,
|
||||
values_optional, value_bit_width));
|
||||
return FixedLengthEncodingParametersV3(delta_bit_width, use_signed_deltas,
|
||||
values_optional, value_bit_width);
|
||||
}
|
||||
|
||||
uint64_t FixedLengthEncodingParametersV3::DeltaHeaderAsInt() const {
|
||||
uint64_t header = delta_bit_width_ - 1;
|
||||
RTC_CHECK_LT(header, 1u << 6);
|
||||
if (signed_deltas_) {
|
||||
header += 1u << 6;
|
||||
}
|
||||
RTC_CHECK_LT(header, 1u << 7);
|
||||
if (values_optional_) {
|
||||
header += 1u << 7;
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
absl::optional<FixedLengthEncodingParametersV3>
|
||||
FixedLengthEncodingParametersV3::ParseDeltaHeader(uint64_t header,
|
||||
uint64_t value_bit_width) {
|
||||
uint64_t delta_bit_width = (header & ((1u << 6) - 1)) + 1;
|
||||
bool signed_deltas = header & (1u << 6);
|
||||
bool values_optional = header & (1u << 7);
|
||||
|
||||
if (header >= (1u << 8)) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to parse delta header; unread bits remaining.";
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
if (!ValidParameters(delta_bit_width, signed_deltas, values_optional,
|
||||
value_bit_width)) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to parse delta header. Invalid combination of "
|
||||
"values: delta_bit_width="
|
||||
<< delta_bit_width << " signed_deltas=" << signed_deltas
|
||||
<< " values_optional=" << values_optional
|
||||
<< " value_bit_width=" << value_bit_width;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
return FixedLengthEncodingParametersV3(delta_bit_width, signed_deltas,
|
||||
values_optional, value_bit_width);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Parameters for fixed-size delta-encoding/decoding.
|
||||
// These are tailored for the sequence which will be encoded (e.g. widths).
|
||||
class FixedLengthEncodingParametersV3 final {
|
||||
public:
|
||||
static bool ValidParameters(uint64_t delta_bit_width,
|
||||
bool signed_deltas,
|
||||
bool values_optional,
|
||||
uint64_t value_bit_width) {
|
||||
return (1 <= delta_bit_width && delta_bit_width <= 64 &&
|
||||
1 <= value_bit_width && value_bit_width <= 64 &&
|
||||
(delta_bit_width <= value_bit_width ||
|
||||
(signed_deltas && delta_bit_width == 64)));
|
||||
}
|
||||
|
||||
static FixedLengthEncodingParametersV3 CalculateParameters(
|
||||
uint64_t base,
|
||||
rtc::ArrayView<const uint64_t> values,
|
||||
uint64_t value_bit_width,
|
||||
bool values_optional);
|
||||
static absl::optional<FixedLengthEncodingParametersV3> ParseDeltaHeader(
|
||||
uint64_t header,
|
||||
uint64_t value_bit_width);
|
||||
|
||||
uint64_t DeltaHeaderAsInt() const;
|
||||
|
||||
// Number of bits necessary to hold the widest(*) of the deltas between the
|
||||
// values in the sequence.
|
||||
// (*) - Widest might not be the largest, if signed deltas are used.
|
||||
uint64_t delta_bit_width() const { return delta_bit_width_; }
|
||||
|
||||
// Whether deltas are signed.
|
||||
bool signed_deltas() const { return signed_deltas_; }
|
||||
|
||||
// Whether the values of the sequence are optional. That is, it may be
|
||||
// that some of them do not have a value (not even a sentinel value indicating
|
||||
// invalidity).
|
||||
bool values_optional() const { return values_optional_; }
|
||||
|
||||
// Whether all values are equal. 64-bit signed deltas are assumed to not
|
||||
// occur, since those could equally well be represented using 64 bit unsigned
|
||||
// deltas.
|
||||
bool values_equal() const {
|
||||
return delta_bit_width() == 64 && signed_deltas();
|
||||
}
|
||||
|
||||
// Number of bits necessary to hold the largest value in the sequence.
|
||||
uint64_t value_bit_width() const { return value_bit_width_; }
|
||||
|
||||
// Masks where only the bits relevant to the deltas/values are turned on.
|
||||
uint64_t delta_mask() const { return delta_mask_; }
|
||||
uint64_t value_mask() const { return value_mask_; }
|
||||
|
||||
private:
|
||||
FixedLengthEncodingParametersV3(uint64_t delta_bit_width,
|
||||
bool signed_deltas,
|
||||
bool values_optional,
|
||||
uint64_t value_bit_width)
|
||||
: delta_bit_width_(delta_bit_width),
|
||||
signed_deltas_(signed_deltas),
|
||||
values_optional_(values_optional),
|
||||
value_bit_width_(value_bit_width),
|
||||
delta_mask_(
|
||||
webrtc_event_logging::MaxUnsignedValueOfBitWidth(delta_bit_width_)),
|
||||
value_mask_(webrtc_event_logging::MaxUnsignedValueOfBitWidth(
|
||||
value_bit_width_)) {}
|
||||
|
||||
uint64_t delta_bit_width_;
|
||||
bool signed_deltas_;
|
||||
bool values_optional_;
|
||||
uint64_t value_bit_width_;
|
||||
|
||||
uint64_t delta_mask_;
|
||||
uint64_t value_mask_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright 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_LOGGED_RTP_RTCP_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_LOGGED_RTP_RTCP_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/rtp_headers.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedRtpPacket {
|
||||
LoggedRtpPacket(Timestamp timestamp,
|
||||
RTPHeader header,
|
||||
size_t header_length,
|
||||
size_t total_length)
|
||||
: timestamp(timestamp),
|
||||
header(header),
|
||||
header_length(header_length),
|
||||
total_length(total_length) {}
|
||||
|
||||
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;
|
||||
// TODO(terelius): This allocates space for 15 CSRCs even if none are used.
|
||||
RTPHeader header;
|
||||
// RTPHeader::extension is a mess, save DD wire format instead.
|
||||
std::vector<uint8_t> dependency_descriptor_wire_format;
|
||||
size_t header_length;
|
||||
size_t total_length;
|
||||
};
|
||||
|
||||
struct LoggedRtpPacketIncoming {
|
||||
LoggedRtpPacketIncoming(Timestamp timestamp,
|
||||
RTPHeader header,
|
||||
size_t header_length,
|
||||
size_t total_length)
|
||||
: rtp(timestamp, header, header_length, total_length) {}
|
||||
int64_t log_time_us() const { return rtp.timestamp.us(); }
|
||||
int64_t log_time_ms() const { return rtp.timestamp.ms(); }
|
||||
Timestamp log_time() const { return rtp.timestamp; }
|
||||
|
||||
LoggedRtpPacket rtp;
|
||||
};
|
||||
|
||||
struct LoggedRtpPacketOutgoing {
|
||||
LoggedRtpPacketOutgoing(Timestamp timestamp,
|
||||
RTPHeader header,
|
||||
size_t header_length,
|
||||
size_t total_length)
|
||||
: rtp(timestamp, header, header_length, total_length) {}
|
||||
int64_t log_time_us() const { return rtp.timestamp.us(); }
|
||||
int64_t log_time_ms() const { return rtp.timestamp.ms(); }
|
||||
Timestamp log_time() const { return rtp.timestamp; }
|
||||
|
||||
LoggedRtpPacket rtp;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacket {
|
||||
LoggedRtcpPacket(Timestamp timestamp, const std::vector<uint8_t>& packet)
|
||||
: timestamp(timestamp), raw_data(packet) {}
|
||||
LoggedRtcpPacket(Timestamp timestamp, absl::string_view packet)
|
||||
: timestamp(timestamp), raw_data(packet.size()) {
|
||||
memcpy(raw_data.data(), packet.data(), packet.size());
|
||||
}
|
||||
|
||||
LoggedRtcpPacket(const LoggedRtcpPacket& rhs) = default;
|
||||
|
||||
~LoggedRtcpPacket() = default;
|
||||
|
||||
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;
|
||||
std::vector<uint8_t> raw_data;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketIncoming {
|
||||
LoggedRtcpPacketIncoming(Timestamp timestamp,
|
||||
const std::vector<uint8_t>& packet)
|
||||
: rtcp(timestamp, packet) {}
|
||||
LoggedRtcpPacketIncoming(Timestamp timestamp, absl::string_view packet)
|
||||
: rtcp(timestamp, packet) {}
|
||||
|
||||
int64_t log_time_us() const { return rtcp.timestamp.us(); }
|
||||
int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
|
||||
Timestamp log_time() const { return rtcp.timestamp; }
|
||||
|
||||
LoggedRtcpPacket rtcp;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketOutgoing {
|
||||
LoggedRtcpPacketOutgoing(Timestamp timestamp,
|
||||
const std::vector<uint8_t>& packet)
|
||||
: rtcp(timestamp, packet) {}
|
||||
LoggedRtcpPacketOutgoing(Timestamp timestamp, absl::string_view packet)
|
||||
: rtcp(timestamp, packet) {}
|
||||
|
||||
int64_t log_time_us() const { return rtcp.timestamp.us(); }
|
||||
int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
|
||||
Timestamp log_time() const { return rtcp.timestamp; }
|
||||
|
||||
LoggedRtcpPacket rtcp;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketReceiverReport {
|
||||
LoggedRtcpPacketReceiverReport() = default;
|
||||
LoggedRtcpPacketReceiverReport(Timestamp timestamp,
|
||||
const rtcp::ReceiverReport& rr)
|
||||
: timestamp(timestamp), rr(rr) {}
|
||||
|
||||
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();
|
||||
rtcp::ReceiverReport rr;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketSenderReport {
|
||||
LoggedRtcpPacketSenderReport() = default;
|
||||
LoggedRtcpPacketSenderReport(Timestamp timestamp,
|
||||
const rtcp::SenderReport& sr)
|
||||
: timestamp(timestamp), sr(sr) {}
|
||||
|
||||
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();
|
||||
rtcp::SenderReport sr;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketExtendedReports {
|
||||
LoggedRtcpPacketExtendedReports() = default;
|
||||
|
||||
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();
|
||||
rtcp::ExtendedReports xr;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketRemb {
|
||||
LoggedRtcpPacketRemb() = default;
|
||||
LoggedRtcpPacketRemb(Timestamp timestamp, const rtcp::Remb& remb)
|
||||
: timestamp(timestamp), remb(remb) {}
|
||||
|
||||
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();
|
||||
rtcp::Remb remb;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketNack {
|
||||
LoggedRtcpPacketNack() = default;
|
||||
LoggedRtcpPacketNack(Timestamp timestamp, const rtcp::Nack& nack)
|
||||
: timestamp(timestamp), nack(nack) {}
|
||||
|
||||
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();
|
||||
rtcp::Nack nack;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketFir {
|
||||
LoggedRtcpPacketFir() = default;
|
||||
|
||||
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();
|
||||
rtcp::Fir fir;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketPli {
|
||||
LoggedRtcpPacketPli() = default;
|
||||
|
||||
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();
|
||||
rtcp::Pli pli;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketTransportFeedback {
|
||||
LoggedRtcpPacketTransportFeedback()
|
||||
: transport_feedback(/*include_timestamps=*/true) {}
|
||||
LoggedRtcpPacketTransportFeedback(
|
||||
Timestamp timestamp,
|
||||
const rtcp::TransportFeedback& transport_feedback)
|
||||
: timestamp(timestamp), transport_feedback(transport_feedback) {}
|
||||
|
||||
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();
|
||||
rtcp::TransportFeedback transport_feedback;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketLossNotification {
|
||||
LoggedRtcpPacketLossNotification() = default;
|
||||
LoggedRtcpPacketLossNotification(
|
||||
Timestamp timestamp,
|
||||
const rtcp::LossNotification& loss_notification)
|
||||
: timestamp(timestamp), loss_notification(loss_notification) {}
|
||||
|
||||
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();
|
||||
rtcp::LossNotification loss_notification;
|
||||
};
|
||||
|
||||
struct LoggedRtcpPacketBye {
|
||||
LoggedRtcpPacketBye() = default;
|
||||
|
||||
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();
|
||||
rtcp::Bye bye;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_LOGGED_RTP_RTCP_H_
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_alr_state.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
constexpr RtcEvent::Type RtcEventAlrState::kType;
|
||||
constexpr RtcEventDefinition<RtcEventAlrState, LoggedAlrStateEvent, bool>
|
||||
RtcEventAlrState::definition_;
|
||||
|
||||
RtcEventAlrState::RtcEventAlrState(bool in_alr) : in_alr_(in_alr) {}
|
||||
|
||||
RtcEventAlrState::RtcEventAlrState(const RtcEventAlrState& other)
|
||||
: RtcEvent(other.timestamp_us_), in_alr_(other.in_alr_) {}
|
||||
|
||||
RtcEventAlrState::~RtcEventAlrState() = default;
|
||||
|
||||
std::unique_ptr<RtcEventAlrState> RtcEventAlrState::Copy() const {
|
||||
return absl::WrapUnique<RtcEventAlrState>(new RtcEventAlrState(*this));
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus RtcEventAlrState::Parse(
|
||||
absl::string_view s,
|
||||
bool batched,
|
||||
std::vector<LoggedAlrStateEvent>& output) {
|
||||
return RtcEventAlrState::definition_.ParseBatch(s, batched, output);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ALR_STATE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#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 LoggedAlrStateEvent {
|
||||
LoggedAlrStateEvent() = default;
|
||||
LoggedAlrStateEvent(Timestamp timestamp, bool in_alr)
|
||||
: timestamp(timestamp), in_alr(in_alr) {}
|
||||
|
||||
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();
|
||||
bool in_alr;
|
||||
};
|
||||
|
||||
class RtcEventAlrState final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::AlrStateEvent;
|
||||
|
||||
explicit RtcEventAlrState(bool in_alr);
|
||||
~RtcEventAlrState() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventAlrState> Copy() const;
|
||||
|
||||
bool in_alr() const { return in_alr_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
return RtcEventAlrState::definition_.EncodeBatch(batch);
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(absl::string_view s,
|
||||
bool batched,
|
||||
std::vector<LoggedAlrStateEvent>& output);
|
||||
|
||||
private:
|
||||
RtcEventAlrState(const RtcEventAlrState& other);
|
||||
|
||||
const bool in_alr_;
|
||||
|
||||
static constexpr RtcEventDefinition<RtcEventAlrState,
|
||||
LoggedAlrStateEvent,
|
||||
bool>
|
||||
definition_{{"AlrState", RtcEventAlrState::kType},
|
||||
{&RtcEventAlrState::in_alr_,
|
||||
&LoggedAlrStateEvent::in_alr,
|
||||
{"in_alr", /*id=*/1, FieldType::kFixed8, /*width=*/1}}};
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_audio_network_adaptation.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventAudioNetworkAdaptation::RtcEventAudioNetworkAdaptation(
|
||||
std::unique_ptr<AudioEncoderRuntimeConfig> config)
|
||||
: config_(std::move(config)) {
|
||||
RTC_DCHECK(config_);
|
||||
}
|
||||
|
||||
RtcEventAudioNetworkAdaptation::RtcEventAudioNetworkAdaptation(
|
||||
const RtcEventAudioNetworkAdaptation& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
config_(std::make_unique<AudioEncoderRuntimeConfig>(*other.config_)) {}
|
||||
|
||||
RtcEventAudioNetworkAdaptation::~RtcEventAudioNetworkAdaptation() = default;
|
||||
|
||||
std::unique_ptr<RtcEventAudioNetworkAdaptation>
|
||||
RtcEventAudioNetworkAdaptation::Copy() const {
|
||||
return absl::WrapUnique(new RtcEventAudioNetworkAdaptation(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_AUDIO_NETWORK_ADAPTATION_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_NETWORK_ADAPTATION_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedAudioNetworkAdaptationEvent {
|
||||
LoggedAudioNetworkAdaptationEvent() = default;
|
||||
LoggedAudioNetworkAdaptationEvent(Timestamp timestamp,
|
||||
const AudioEncoderRuntimeConfig& config)
|
||||
: timestamp(timestamp), config(config) {}
|
||||
|
||||
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();
|
||||
AudioEncoderRuntimeConfig config;
|
||||
};
|
||||
|
||||
struct AudioEncoderRuntimeConfig;
|
||||
|
||||
class RtcEventAudioNetworkAdaptation final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::AudioNetworkAdaptation;
|
||||
|
||||
explicit RtcEventAudioNetworkAdaptation(
|
||||
std::unique_ptr<AudioEncoderRuntimeConfig> config);
|
||||
~RtcEventAudioNetworkAdaptation() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventAudioNetworkAdaptation> Copy() const;
|
||||
|
||||
const AudioEncoderRuntimeConfig& config() const { return *config_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedAudioNetworkAdaptationEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventAudioNetworkAdaptation(const RtcEventAudioNetworkAdaptation& other);
|
||||
|
||||
const std::unique_ptr<const AudioEncoderRuntimeConfig> config_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_NETWORK_ADAPTATION_H_
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_audio_playout.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr RtcEventDefinition<RtcEventAudioPlayout,
|
||||
LoggedAudioPlayoutEvent,
|
||||
uint32_t>
|
||||
RtcEventAudioPlayout::definition_;
|
||||
|
||||
RtcEventAudioPlayout::RtcEventAudioPlayout(uint32_t ssrc) : ssrc_(ssrc) {}
|
||||
|
||||
RtcEventAudioPlayout::RtcEventAudioPlayout(const RtcEventAudioPlayout& other)
|
||||
: RtcEvent(other.timestamp_us_), ssrc_(other.ssrc_) {}
|
||||
|
||||
std::unique_ptr<RtcEventAudioPlayout> RtcEventAudioPlayout::Copy() const {
|
||||
return absl::WrapUnique<RtcEventAudioPlayout>(
|
||||
new RtcEventAudioPlayout(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_AUDIO_PLAYOUT_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 LoggedAudioPlayoutEvent {
|
||||
LoggedAudioPlayoutEvent() = default;
|
||||
LoggedAudioPlayoutEvent(Timestamp timestamp, uint32_t ssrc)
|
||||
: timestamp(timestamp), ssrc(ssrc) {}
|
||||
|
||||
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 ssrc;
|
||||
};
|
||||
|
||||
class RtcEventAudioPlayout final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::AudioPlayout;
|
||||
|
||||
explicit RtcEventAudioPlayout(uint32_t ssrc);
|
||||
~RtcEventAudioPlayout() override = default;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventAudioPlayout> Copy() const;
|
||||
|
||||
uint32_t ssrc() const { return ssrc_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
return RtcEventAudioPlayout::definition_.EncodeBatch(batch);
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>& output) {
|
||||
std::vector<LoggedAudioPlayoutEvent> temp_output;
|
||||
auto status = RtcEventAudioPlayout::definition_.ParseBatch(
|
||||
encoded_bytes, batched, temp_output);
|
||||
for (const LoggedAudioPlayoutEvent& event : temp_output) {
|
||||
output[event.ssrc].push_back(event);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventAudioPlayout(const RtcEventAudioPlayout& other);
|
||||
|
||||
const uint32_t ssrc_;
|
||||
|
||||
static constexpr RtcEventDefinition<RtcEventAudioPlayout,
|
||||
LoggedAudioPlayoutEvent,
|
||||
uint32_t>
|
||||
definition_{{"AudioPlayout", RtcEventAudioPlayout::kType},
|
||||
{&RtcEventAudioPlayout::ssrc_,
|
||||
&LoggedAudioPlayoutEvent::ssrc,
|
||||
{"ssrc", /*id=*/1, FieldType::kFixed32, /*width=*/32}}};
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_audio_receive_stream_config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventAudioReceiveStreamConfig::RtcEventAudioReceiveStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config)
|
||||
: config_(std::move(config)) {
|
||||
RTC_DCHECK(config_);
|
||||
}
|
||||
|
||||
RtcEventAudioReceiveStreamConfig::RtcEventAudioReceiveStreamConfig(
|
||||
const RtcEventAudioReceiveStreamConfig& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
|
||||
|
||||
RtcEventAudioReceiveStreamConfig::~RtcEventAudioReceiveStreamConfig() = default;
|
||||
|
||||
std::unique_ptr<RtcEventAudioReceiveStreamConfig>
|
||||
RtcEventAudioReceiveStreamConfig::Copy() const {
|
||||
return absl::WrapUnique<RtcEventAudioReceiveStreamConfig>(
|
||||
new RtcEventAudioReceiveStreamConfig(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_AUDIO_RECEIVE_STREAM_CONFIG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_RECEIVE_STREAM_CONFIG_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedAudioRecvConfig {
|
||||
LoggedAudioRecvConfig() = default;
|
||||
LoggedAudioRecvConfig(Timestamp timestamp, const rtclog::StreamConfig config)
|
||||
: timestamp(timestamp), config(config) {}
|
||||
|
||||
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();
|
||||
rtclog::StreamConfig config;
|
||||
};
|
||||
|
||||
class RtcEventAudioReceiveStreamConfig final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::AudioReceiveStreamConfig;
|
||||
|
||||
explicit RtcEventAudioReceiveStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config);
|
||||
~RtcEventAudioReceiveStreamConfig() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return true; }
|
||||
|
||||
std::unique_ptr<RtcEventAudioReceiveStreamConfig> Copy() const;
|
||||
|
||||
const rtclog::StreamConfig& config() const { return *config_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedAudioRecvConfig>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventAudioReceiveStreamConfig(
|
||||
const RtcEventAudioReceiveStreamConfig& other);
|
||||
|
||||
const std::unique_ptr<const rtclog::StreamConfig> config_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_RECEIVE_STREAM_CONFIG_H_
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_audio_send_stream_config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventAudioSendStreamConfig::RtcEventAudioSendStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config)
|
||||
: config_(std::move(config)) {
|
||||
RTC_DCHECK(config_);
|
||||
}
|
||||
|
||||
RtcEventAudioSendStreamConfig::RtcEventAudioSendStreamConfig(
|
||||
const RtcEventAudioSendStreamConfig& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
|
||||
|
||||
RtcEventAudioSendStreamConfig::~RtcEventAudioSendStreamConfig() = default;
|
||||
|
||||
std::unique_ptr<RtcEventAudioSendStreamConfig>
|
||||
RtcEventAudioSendStreamConfig::Copy() const {
|
||||
return absl::WrapUnique<RtcEventAudioSendStreamConfig>(
|
||||
new RtcEventAudioSendStreamConfig(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_AUDIO_SEND_STREAM_CONFIG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_SEND_STREAM_CONFIG_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedAudioSendConfig {
|
||||
LoggedAudioSendConfig() = default;
|
||||
LoggedAudioSendConfig(Timestamp timestamp, const rtclog::StreamConfig config)
|
||||
: timestamp(timestamp), config(config) {}
|
||||
|
||||
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();
|
||||
rtclog::StreamConfig config;
|
||||
};
|
||||
|
||||
class RtcEventAudioSendStreamConfig final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::AudioSendStreamConfig;
|
||||
|
||||
explicit RtcEventAudioSendStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config);
|
||||
~RtcEventAudioSendStreamConfig() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return true; }
|
||||
|
||||
std::unique_ptr<RtcEventAudioSendStreamConfig> Copy() const;
|
||||
|
||||
const rtclog::StreamConfig& config() const { return *config_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedAudioSendConfig>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventAudioSendStreamConfig(const RtcEventAudioSendStreamConfig& other);
|
||||
|
||||
const std::unique_ptr<const rtclog::StreamConfig> config_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_SEND_STREAM_CONFIG_H_
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#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();
|
||||
status = PopulateRtcEventTimestamp(
|
||||
result.value(), &LoggedStartEvent::timestamp, output_batch);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
result = parser.ParseNumericField(utc_start_time_params_);
|
||||
if (!result.ok())
|
||||
return result.status();
|
||||
status = PopulateRtcEventTimestamp(
|
||||
result.value(), &LoggedStartEvent::utc_start_time, output_batch);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 log_time() const { return timestamp; }
|
||||
|
||||
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_
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_bwe_update_delay_based.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr RtcEventDefinition<RtcEventBweUpdateDelayBased,
|
||||
LoggedBweDelayBasedUpdate,
|
||||
int32_t,
|
||||
BandwidthUsage>
|
||||
RtcEventBweUpdateDelayBased::definition_;
|
||||
|
||||
RtcEventBweUpdateDelayBased::RtcEventBweUpdateDelayBased(
|
||||
int32_t bitrate_bps,
|
||||
BandwidthUsage detector_state)
|
||||
: bitrate_bps_(bitrate_bps), detector_state_(detector_state) {}
|
||||
|
||||
RtcEventBweUpdateDelayBased::RtcEventBweUpdateDelayBased(
|
||||
const RtcEventBweUpdateDelayBased& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
bitrate_bps_(other.bitrate_bps_),
|
||||
detector_state_(other.detector_state_) {}
|
||||
|
||||
RtcEventBweUpdateDelayBased::~RtcEventBweUpdateDelayBased() = default;
|
||||
|
||||
std::unique_ptr<RtcEventBweUpdateDelayBased> RtcEventBweUpdateDelayBased::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventBweUpdateDelayBased>(
|
||||
new RtcEventBweUpdateDelayBased(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_BWE_UPDATE_DELAY_BASED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/network_state_predictor.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 {
|
||||
|
||||
// Separate the event log encoding from the enum values.
|
||||
// As long as the enum values are the same as the encodings,
|
||||
// the two conversion functions can be compiled to (roughly)
|
||||
// a range check each.
|
||||
template <>
|
||||
class RtcEventLogEnum<BandwidthUsage> {
|
||||
static constexpr uint64_t kBwNormal = 0;
|
||||
static constexpr uint64_t kBwUnderusing = 1;
|
||||
static constexpr uint64_t kBwOverusing = 2;
|
||||
|
||||
public:
|
||||
static uint64_t Encode(BandwidthUsage x) {
|
||||
switch (x) {
|
||||
case BandwidthUsage::kBwNormal:
|
||||
return kBwNormal;
|
||||
case BandwidthUsage::kBwUnderusing:
|
||||
return kBwUnderusing;
|
||||
case BandwidthUsage::kBwOverusing:
|
||||
return kBwOverusing;
|
||||
case BandwidthUsage::kLast:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
static RtcEventLogParseStatusOr<BandwidthUsage> Decode(uint64_t x) {
|
||||
switch (x) {
|
||||
case kBwNormal:
|
||||
return BandwidthUsage::kBwNormal;
|
||||
case kBwUnderusing:
|
||||
return BandwidthUsage::kBwUnderusing;
|
||||
case kBwOverusing:
|
||||
return BandwidthUsage::kBwOverusing;
|
||||
}
|
||||
return RtcEventLogParseStatus::Error("Failed to decode BandwidthUsage enum",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
};
|
||||
|
||||
struct LoggedBweDelayBasedUpdate {
|
||||
LoggedBweDelayBasedUpdate() = default;
|
||||
LoggedBweDelayBasedUpdate(Timestamp timestamp,
|
||||
int32_t bitrate_bps,
|
||||
BandwidthUsage detector_state)
|
||||
: timestamp(timestamp),
|
||||
bitrate_bps(bitrate_bps),
|
||||
detector_state(detector_state) {}
|
||||
|
||||
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();
|
||||
int32_t bitrate_bps;
|
||||
BandwidthUsage detector_state;
|
||||
};
|
||||
|
||||
class RtcEventBweUpdateDelayBased final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::BweUpdateDelayBased;
|
||||
|
||||
RtcEventBweUpdateDelayBased(int32_t bitrate_bps,
|
||||
BandwidthUsage detector_state);
|
||||
~RtcEventBweUpdateDelayBased() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventBweUpdateDelayBased> Copy() const;
|
||||
|
||||
int32_t bitrate_bps() const { return bitrate_bps_; }
|
||||
BandwidthUsage detector_state() const { return detector_state_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
return RtcEventBweUpdateDelayBased::definition_.EncodeBatch(batch);
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedBweDelayBasedUpdate>& output) {
|
||||
return RtcEventBweUpdateDelayBased::definition_.ParseBatch(encoded_bytes,
|
||||
batched, output);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventBweUpdateDelayBased(const RtcEventBweUpdateDelayBased& other);
|
||||
|
||||
const int32_t bitrate_bps_;
|
||||
const BandwidthUsage detector_state_;
|
||||
|
||||
static constexpr RtcEventDefinition<RtcEventBweUpdateDelayBased,
|
||||
LoggedBweDelayBasedUpdate,
|
||||
int32_t,
|
||||
BandwidthUsage>
|
||||
definition_{
|
||||
{"BweDelayBased", RtcEventBweUpdateDelayBased::kType},
|
||||
{&RtcEventBweUpdateDelayBased::bitrate_bps_,
|
||||
&LoggedBweDelayBasedUpdate::bitrate_bps,
|
||||
{"bitrate_bps", /*id=*/1, FieldType::kVarInt, /*width=*/32}},
|
||||
{&RtcEventBweUpdateDelayBased::detector_state_,
|
||||
&LoggedBweDelayBasedUpdate::detector_state,
|
||||
{"detector_state", /*id=*/2, FieldType::kVarInt, /*width=*/64}}};
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_bwe_update_loss_based.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventBweUpdateLossBased::RtcEventBweUpdateLossBased(int32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets)
|
||||
: bitrate_bps_(bitrate_bps),
|
||||
fraction_loss_(fraction_loss),
|
||||
total_packets_(total_packets) {}
|
||||
|
||||
RtcEventBweUpdateLossBased::RtcEventBweUpdateLossBased(
|
||||
const RtcEventBweUpdateLossBased& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
bitrate_bps_(other.bitrate_bps_),
|
||||
fraction_loss_(other.fraction_loss_),
|
||||
total_packets_(other.total_packets_) {}
|
||||
|
||||
RtcEventBweUpdateLossBased::~RtcEventBweUpdateLossBased() = default;
|
||||
|
||||
std::unique_ptr<RtcEventBweUpdateLossBased> RtcEventBweUpdateLossBased::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventBweUpdateLossBased>(
|
||||
new RtcEventBweUpdateLossBased(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_BWE_UPDATE_LOSS_BASED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedBweLossBasedUpdate {
|
||||
LoggedBweLossBasedUpdate() = default;
|
||||
LoggedBweLossBasedUpdate(Timestamp timestamp,
|
||||
int32_t bitrate_bps,
|
||||
uint8_t fraction_lost,
|
||||
int32_t expected_packets)
|
||||
: timestamp(timestamp),
|
||||
bitrate_bps(bitrate_bps),
|
||||
fraction_lost(fraction_lost),
|
||||
expected_packets(expected_packets) {}
|
||||
|
||||
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();
|
||||
int32_t bitrate_bps;
|
||||
uint8_t fraction_lost;
|
||||
int32_t expected_packets;
|
||||
};
|
||||
|
||||
class RtcEventBweUpdateLossBased final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::BweUpdateLossBased;
|
||||
|
||||
RtcEventBweUpdateLossBased(int32_t bitrate_bps_,
|
||||
uint8_t fraction_loss_,
|
||||
int32_t total_packets_);
|
||||
~RtcEventBweUpdateLossBased() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventBweUpdateLossBased> Copy() const;
|
||||
|
||||
int32_t bitrate_bps() const { return bitrate_bps_; }
|
||||
uint8_t fraction_loss() const { return fraction_loss_; }
|
||||
int32_t total_packets() const { return total_packets_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedBweLossBasedUpdate>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventBweUpdateLossBased(const RtcEventBweUpdateLossBased& other);
|
||||
|
||||
const int32_t bitrate_bps_;
|
||||
const uint8_t fraction_loss_;
|
||||
const int32_t total_packets_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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_DEFINITION_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.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"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
template <typename EventType, typename LoggedType, typename T>
|
||||
struct RtcEventFieldDefinition {
|
||||
const T EventType::*event_member;
|
||||
T LoggedType::*logged_member;
|
||||
FieldParameters params;
|
||||
};
|
||||
|
||||
// Base case
|
||||
template <typename EventType, typename LoggedType, typename... Ts>
|
||||
class RtcEventDefinitionImpl {
|
||||
public:
|
||||
void EncodeImpl(EventEncoder&, rtc::ArrayView<const RtcEvent*>) const {}
|
||||
RtcEventLogParseStatus ParseImpl(EventParser&,
|
||||
rtc::ArrayView<LoggedType>) const {
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
};
|
||||
|
||||
// Recursive case
|
||||
template <typename EventType, typename LoggedType, typename T, typename... Ts>
|
||||
class RtcEventDefinitionImpl<EventType, LoggedType, T, Ts...> {
|
||||
public:
|
||||
constexpr RtcEventDefinitionImpl(
|
||||
RtcEventFieldDefinition<EventType, LoggedType, T> field,
|
||||
RtcEventFieldDefinition<EventType, LoggedType, Ts>... rest)
|
||||
: field_(field), rest_(rest...) {}
|
||||
|
||||
void EncodeImpl(EventEncoder& encoder,
|
||||
rtc::ArrayView<const RtcEvent*> batch) const {
|
||||
auto values = ExtractRtcEventMember(batch, field_.event_member);
|
||||
encoder.EncodeField(field_.params, values);
|
||||
rest_.EncodeImpl(encoder, batch);
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus ParseImpl(
|
||||
EventParser& parser,
|
||||
rtc::ArrayView<LoggedType> output_batch) const {
|
||||
RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
|
||||
parser.ParseNumericField(field_.params);
|
||||
if (!result.ok())
|
||||
return result.status();
|
||||
auto status = PopulateRtcEventMember(result.value(), field_.logged_member,
|
||||
output_batch);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
return rest_.ParseImpl(parser, output_batch);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventFieldDefinition<EventType, LoggedType, T> field_;
|
||||
RtcEventDefinitionImpl<EventType, LoggedType, Ts...> rest_;
|
||||
};
|
||||
|
||||
// The RtcEventDefinition sets up a mapping between the fields
|
||||
// in an RtcEvent and the corresponding fields in the parsed struct.
|
||||
// For example, an RtcFoo class containing two fields; `uint32_t bar`
|
||||
// and `bool baz` (a log timestamp is always implicitly added)
|
||||
// might have a definition
|
||||
// RtcEventDefinition<RtcFoo, LoggedFoo, uint32_t, bool>(
|
||||
// {"foo", RtcFoo::Type},
|
||||
// {&RtcFoo::bar_, &LoggedFoo::bar, {"bar", 1, FieldType::kVarInt, 32}},
|
||||
// {&RtcFoo::baz_, &LoggedFoo::baz, {"baz", 2, FieldType::kFixed8, 1}},
|
||||
// );
|
||||
// In addition to defining string names to aid debugging,
|
||||
// this specifies that
|
||||
// * RtcFoo::Type uniquely identifies an RtcFoo in the encoded stream
|
||||
// * The `bar` field has ID 1, is encoded as a VarInt
|
||||
// (when not delta compressed), and wraps around after 32 bits.
|
||||
// * The `baz` field has ID 2, is encoded as an 8-bit field
|
||||
// (when not delta compressed), and wraps around after 1 bit.
|
||||
// Note that the numerical field and event IDs can't be changed since
|
||||
// that would break compatibility with old logs.
|
||||
// In most cases (including all cases where wrap around isn't
|
||||
// expected), the wrap around should be equal to the bitwidth of
|
||||
// the field.
|
||||
template <typename EventType, typename LoggedType, typename... Ts>
|
||||
class RtcEventDefinition {
|
||||
public:
|
||||
constexpr RtcEventDefinition(
|
||||
EventParameters params,
|
||||
RtcEventFieldDefinition<EventType, LoggedType, Ts>... fields)
|
||||
: params_(params), fields_(fields...) {}
|
||||
|
||||
std::string EncodeBatch(rtc::ArrayView<const RtcEvent*> batch) const {
|
||||
EventEncoder encoder(params_, batch);
|
||||
fields_.EncodeImpl(encoder, batch);
|
||||
return encoder.AsString();
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus ParseBatch(absl::string_view s,
|
||||
bool batched,
|
||||
std::vector<LoggedType>& output) const {
|
||||
EventParser parser;
|
||||
auto status = parser.Initialize(s, batched);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
rtc::ArrayView<LoggedType> 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();
|
||||
status = PopulateRtcEventTimestamp(result.value(), &LoggedType::timestamp,
|
||||
output_batch);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
return fields_.ParseImpl(parser, output_batch);
|
||||
}
|
||||
|
||||
private:
|
||||
EventParameters params_;
|
||||
RtcEventDefinitionImpl<EventType, LoggedType, Ts...> fields_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_dtls_transport_state.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventDtlsTransportState::RtcEventDtlsTransportState(DtlsTransportState state)
|
||||
: dtls_transport_state_(state) {}
|
||||
|
||||
RtcEventDtlsTransportState::RtcEventDtlsTransportState(
|
||||
const RtcEventDtlsTransportState& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
dtls_transport_state_(other.dtls_transport_state_) {}
|
||||
|
||||
RtcEventDtlsTransportState::~RtcEventDtlsTransportState() = default;
|
||||
|
||||
std::unique_ptr<RtcEventDtlsTransportState> RtcEventDtlsTransportState::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventDtlsTransportState>(
|
||||
new RtcEventDtlsTransportState(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_DTLS_TRANSPORT_STATE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_TRANSPORT_STATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/dtls_transport_interface.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedDtlsTransportState {
|
||||
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();
|
||||
DtlsTransportState dtls_transport_state;
|
||||
};
|
||||
|
||||
class RtcEventDtlsTransportState : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::DtlsTransportState;
|
||||
|
||||
explicit RtcEventDtlsTransportState(DtlsTransportState state);
|
||||
~RtcEventDtlsTransportState() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventDtlsTransportState> Copy() const;
|
||||
|
||||
DtlsTransportState dtls_transport_state() const {
|
||||
return dtls_transport_state_;
|
||||
}
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedDtlsTransportState>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventDtlsTransportState(const RtcEventDtlsTransportState& other);
|
||||
|
||||
const DtlsTransportState dtls_transport_state_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_TRANSPORT_STATE_H_
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_dtls_writable_state.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventDtlsWritableState::RtcEventDtlsWritableState(bool writable)
|
||||
: writable_(writable) {}
|
||||
|
||||
RtcEventDtlsWritableState::RtcEventDtlsWritableState(
|
||||
const RtcEventDtlsWritableState& other)
|
||||
: RtcEvent(other.timestamp_us_), writable_(other.writable_) {}
|
||||
|
||||
RtcEventDtlsWritableState::~RtcEventDtlsWritableState() = default;
|
||||
|
||||
std::unique_ptr<RtcEventDtlsWritableState> RtcEventDtlsWritableState::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventDtlsWritableState>(
|
||||
new RtcEventDtlsWritableState(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_DTLS_WRITABLE_STATE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_WRITABLE_STATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedDtlsWritableState {
|
||||
LoggedDtlsWritableState() = default;
|
||||
explicit LoggedDtlsWritableState(bool writable) : writable(writable) {}
|
||||
|
||||
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();
|
||||
bool writable;
|
||||
};
|
||||
|
||||
class RtcEventDtlsWritableState : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::DtlsWritableState;
|
||||
|
||||
explicit RtcEventDtlsWritableState(bool writable);
|
||||
~RtcEventDtlsWritableState() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventDtlsWritableState> Copy() const;
|
||||
|
||||
bool writable() const { return writable_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedDtlsWritableState>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventDtlsWritableState(const RtcEventDtlsWritableState& other);
|
||||
|
||||
const bool writable_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_WRITABLE_STATE_H_
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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();
|
||||
status = PopulateRtcEventTimestamp(result.value(),
|
||||
&LoggedStopEvent::timestamp, output_batch);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 log_time() const { return timestamp; }
|
||||
|
||||
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_
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* 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_field_encoding.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "logging/rtc_event_log/encoder/bit_writer.h"
|
||||
#include "logging/rtc_event_log/encoder/var_int.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
using webrtc_event_logging::UnsignedDelta;
|
||||
|
||||
namespace {
|
||||
|
||||
std::string SerializeLittleEndian(uint64_t value, uint8_t bytes) {
|
||||
RTC_DCHECK_LE(bytes, sizeof(uint64_t));
|
||||
RTC_DCHECK_GE(bytes, 1);
|
||||
if (bytes < sizeof(uint64_t)) {
|
||||
// Note that shifting a 64-bit value by 64 (or more) bits is undefined.
|
||||
RTC_DCHECK_EQ(value >> (8 * bytes), 0);
|
||||
}
|
||||
std::string output(bytes, 0);
|
||||
// Getting a non-const pointer to the representation. See e.g.
|
||||
// https://en.cppreference.com/w/cpp/string/basic_string:
|
||||
// "The elements of a basic_string are stored contiguously,
|
||||
// that is, [...] a pointer to s[0] can be passed to functions
|
||||
// that expect a pointer to the first element of a null-terminated
|
||||
// CharT[] array."
|
||||
uint8_t* p = reinterpret_cast<uint8_t*>(&output[0]);
|
||||
#ifdef WEBRTC_ARCH_LITTLE_ENDIAN
|
||||
memcpy(p, &value, bytes);
|
||||
#else
|
||||
while (bytes > 0) {
|
||||
*p = static_cast<uint8_t>(value & 0xFF);
|
||||
value >>= 8;
|
||||
++p;
|
||||
--bytes;
|
||||
}
|
||||
#endif // WEBRTC_ARCH_LITTLE_ENDIAN
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string EncodeOptionalValuePositions(std::vector<bool> positions) {
|
||||
BitWriter writer((positions.size() + 7) / 8);
|
||||
for (bool position : positions) {
|
||||
writer.WriteBits(position ? 1u : 0u, 1);
|
||||
}
|
||||
return writer.GetString();
|
||||
}
|
||||
|
||||
std::string EncodeSingleValue(uint64_t value, FieldType field_type) {
|
||||
switch (field_type) {
|
||||
case FieldType::kFixed8:
|
||||
return SerializeLittleEndian(value, /*bytes=*/1);
|
||||
case FieldType::kFixed32:
|
||||
return SerializeLittleEndian(value, /*bytes=*/4);
|
||||
case FieldType::kFixed64:
|
||||
return SerializeLittleEndian(value, /*bytes=*/8);
|
||||
case FieldType::kVarInt:
|
||||
return EncodeVarInt(value);
|
||||
case FieldType::kString:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return std::string();
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
absl::optional<FieldType> ConvertFieldType(uint64_t value) {
|
||||
switch (value) {
|
||||
case static_cast<uint64_t>(FieldType::kFixed8):
|
||||
return FieldType::kFixed8;
|
||||
case static_cast<uint64_t>(FieldType::kFixed32):
|
||||
return FieldType::kFixed32;
|
||||
case static_cast<uint64_t>(FieldType::kFixed64):
|
||||
return FieldType::kFixed64;
|
||||
case static_cast<uint64_t>(FieldType::kVarInt):
|
||||
return FieldType::kVarInt;
|
||||
case static_cast<uint64_t>(FieldType::kString):
|
||||
return FieldType::kString;
|
||||
default:
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::string EncodeDeltasV3(FixedLengthEncodingParametersV3 params,
|
||||
uint64_t base,
|
||||
rtc::ArrayView<const uint64_t> values) {
|
||||
size_t outputbound = (values.size() * params.delta_bit_width() + 7) / 8;
|
||||
BitWriter writer(outputbound);
|
||||
|
||||
uint64_t previous = base;
|
||||
for (uint64_t value : values) {
|
||||
if (params.signed_deltas()) {
|
||||
uint64_t positive_delta =
|
||||
UnsignedDelta(previous, value, params.value_mask());
|
||||
uint64_t negative_delta =
|
||||
UnsignedDelta(value, previous, params.value_mask());
|
||||
uint64_t delta;
|
||||
if (positive_delta <= negative_delta) {
|
||||
delta = positive_delta;
|
||||
} else {
|
||||
// Compute the two's complement representation of a negative
|
||||
// delta, in a field width params_.delta_mask().
|
||||
RTC_DCHECK_GE(params.delta_mask(), negative_delta);
|
||||
RTC_DCHECK_LT(params.delta_mask() - negative_delta,
|
||||
params.delta_mask());
|
||||
delta = params.delta_mask() - negative_delta + 1;
|
||||
RTC_DCHECK_LE(delta, params.delta_mask());
|
||||
}
|
||||
writer.WriteBits(delta, params.delta_bit_width());
|
||||
} else {
|
||||
uint64_t delta = UnsignedDelta(previous, value, params.value_mask());
|
||||
writer.WriteBits(delta, params.delta_bit_width());
|
||||
}
|
||||
previous = value;
|
||||
}
|
||||
|
||||
return writer.GetString();
|
||||
}
|
||||
|
||||
EventEncoder::EventEncoder(EventParameters params,
|
||||
rtc::ArrayView<const RtcEvent*> batch) {
|
||||
batch_size_ = batch.size();
|
||||
if (!batch.empty()) {
|
||||
// Encode event type.
|
||||
uint32_t batched = batch.size() > 1 ? 1 : 0;
|
||||
event_tag_ = (static_cast<uint32_t>(params.id) << 1) + batched;
|
||||
|
||||
// Event tag and number of encoded bytes will be filled in when the
|
||||
// encoding is finalized in AsString().
|
||||
|
||||
// Encode number of events in batch
|
||||
if (batched) {
|
||||
encoded_fields_.push_back(EncodeVarInt(batch.size()));
|
||||
}
|
||||
|
||||
// Encode timestamp
|
||||
std::vector<uint64_t> timestamps;
|
||||
timestamps.reserve(batch.size());
|
||||
for (const RtcEvent* event : batch) {
|
||||
timestamps.push_back(EncodeAsUnsigned(event->timestamp_ms()));
|
||||
}
|
||||
constexpr FieldParameters timestamp_params{"timestamp_ms",
|
||||
FieldParameters::kTimestampField,
|
||||
FieldType::kVarInt, 64};
|
||||
EncodeField(timestamp_params, timestamps);
|
||||
}
|
||||
}
|
||||
|
||||
void EventEncoder::EncodeField(const FieldParameters& params,
|
||||
const ValuesWithPositions& values) {
|
||||
return EncodeField(params, values.values, &values.position_mask);
|
||||
}
|
||||
|
||||
void EventEncoder::EncodeField(const FieldParameters& params,
|
||||
const std::vector<uint64_t>& values,
|
||||
const std::vector<bool>* positions) {
|
||||
if (positions) {
|
||||
RTC_DCHECK_EQ(positions->size(), batch_size_);
|
||||
RTC_DCHECK_LE(values.size(), batch_size_);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(values.size(), batch_size_);
|
||||
}
|
||||
|
||||
if (values.size() == 0) {
|
||||
// If all values for a particular field is empty/nullopt,
|
||||
// then we completely skip the field even if the the batch is non-empty.
|
||||
return;
|
||||
}
|
||||
|
||||
// We know that each event starts with the varint encoded timestamp,
|
||||
// so we omit that field tag (field id + field type). In all other
|
||||
// cases, we write the field tag.
|
||||
if (params.field_id != FieldParameters::kTimestampField) {
|
||||
RTC_DCHECK_LE(params.field_id, std::numeric_limits<uint64_t>::max() >> 3);
|
||||
uint64_t field_tag = params.field_id << 3;
|
||||
field_tag += static_cast<uint64_t>(params.field_type);
|
||||
encoded_fields_.push_back(EncodeVarInt(field_tag));
|
||||
}
|
||||
|
||||
RTC_CHECK_GE(values.size(), 1);
|
||||
if (batch_size_ == 1) {
|
||||
encoded_fields_.push_back(EncodeSingleValue(values[0], params.field_type));
|
||||
return;
|
||||
}
|
||||
|
||||
const bool values_optional = values.size() != batch_size_;
|
||||
|
||||
// Compute delta parameters
|
||||
rtc::ArrayView<const uint64_t> all_values(values);
|
||||
uint64_t base = values[0];
|
||||
rtc::ArrayView<const uint64_t> remaining_values(all_values.subview(1));
|
||||
|
||||
FixedLengthEncodingParametersV3 delta_params =
|
||||
FixedLengthEncodingParametersV3::CalculateParameters(
|
||||
base, remaining_values, params.value_width, values_optional);
|
||||
|
||||
encoded_fields_.push_back(EncodeVarInt(delta_params.DeltaHeaderAsInt()));
|
||||
|
||||
if (values_optional) {
|
||||
RTC_CHECK(positions);
|
||||
encoded_fields_.push_back(EncodeOptionalValuePositions(*positions));
|
||||
}
|
||||
// Base element, encoded as uint8, uint32, uint64 or varint
|
||||
encoded_fields_.push_back(EncodeSingleValue(base, params.field_type));
|
||||
|
||||
// If all (existing) values are equal to the base, then we can skip
|
||||
// writing the all-zero deltas, and instead infer those from the delta
|
||||
// header.
|
||||
if (!delta_params.values_equal()) {
|
||||
encoded_fields_.push_back(
|
||||
EncodeDeltasV3(delta_params, base, remaining_values));
|
||||
}
|
||||
}
|
||||
|
||||
void EventEncoder::EncodeField(const FieldParameters& params,
|
||||
const std::vector<absl::string_view>& values) {
|
||||
RTC_DCHECK_EQ(values.size(), batch_size_);
|
||||
|
||||
if (values.size() == 0) {
|
||||
// If all values for a particular field is empty/nullopt,
|
||||
// then we completely skip the field even if the the batch is non-empty.
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the field tag.
|
||||
RTC_CHECK_NE(params.field_id, FieldParameters::kTimestampField);
|
||||
RTC_DCHECK_LE(params.field_id, std::numeric_limits<uint64_t>::max() >> 3);
|
||||
RTC_DCHECK_EQ(params.field_type, FieldType::kString);
|
||||
uint64_t field_tag = params.field_id << 3;
|
||||
field_tag += static_cast<uint64_t>(params.field_type);
|
||||
encoded_fields_.push_back(EncodeVarInt(field_tag));
|
||||
|
||||
if (values.size() > 1) {
|
||||
// If multiple values in the batch, write the encoding
|
||||
// parameters. (Values >0 reserved for future use.)
|
||||
uint64_t encoding_params = 0;
|
||||
encoded_fields_.push_back(EncodeVarInt(encoding_params));
|
||||
}
|
||||
|
||||
// Write the strings as (length, data) pairs.
|
||||
for (absl::string_view s : values) {
|
||||
encoded_fields_.push_back(EncodeVarInt(s.size()));
|
||||
encoded_fields_.push_back(std::string(s));
|
||||
}
|
||||
}
|
||||
|
||||
std::string EventEncoder::AsString() {
|
||||
std::string encoded_event;
|
||||
|
||||
if (batch_size_ == 0) {
|
||||
RTC_DCHECK_EQ(encoded_fields_.size(), 0);
|
||||
return encoded_event;
|
||||
}
|
||||
|
||||
// Compute size of encoded fields.
|
||||
size_t total_fields_size = 0;
|
||||
for (const std::string& s : encoded_fields_) {
|
||||
total_fields_size += s.size();
|
||||
}
|
||||
|
||||
constexpr size_t kExpectedMaxEventTagBytes = 4;
|
||||
constexpr size_t kExpectedMaxSizeEncodingBytes = 4;
|
||||
encoded_event.reserve(kExpectedMaxEventTagBytes +
|
||||
kExpectedMaxSizeEncodingBytes + total_fields_size);
|
||||
|
||||
// Encode event tag (event id and whether batch or single event).
|
||||
encoded_event.append(EncodeVarInt(event_tag_));
|
||||
|
||||
// Encode size of the remaining fields.
|
||||
encoded_event.append(EncodeVarInt(total_fields_size));
|
||||
|
||||
// Append encoded fields.
|
||||
for (const std::string& s : encoded_fields_) {
|
||||
encoded_event.append(s);
|
||||
}
|
||||
|
||||
return encoded_event;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* 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_FIELD_ENCODING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
|
||||
#include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// To maintain backwards compatibility with past (or future) logs,
|
||||
// the constants in this enum must not be changed.
|
||||
// New field types with numerical IDs 5-7 can be added, but old
|
||||
// parsers will fail to parse events containing the new fields.
|
||||
enum class FieldType : uint8_t {
|
||||
kFixed8 = 0,
|
||||
kFixed32 = 1,
|
||||
kFixed64 = 2,
|
||||
kVarInt = 3,
|
||||
kString = 4,
|
||||
};
|
||||
|
||||
// EventParameters map an event name to a numerical ID.
|
||||
struct EventParameters {
|
||||
// The name is primarily used for debugging purposes.
|
||||
const char* const name;
|
||||
//
|
||||
const RtcEvent::Type id;
|
||||
};
|
||||
|
||||
// FieldParameters define the encoding for a field.
|
||||
struct FieldParameters {
|
||||
// The name is primarily used for debugging purposes.
|
||||
const char* const name;
|
||||
// Numerical ID for the field. Must be strictly greater than 0,
|
||||
// and unique within each event type.
|
||||
const uint64_t field_id;
|
||||
// Encoding type for the base (i.e. non-delta) field in a batch.
|
||||
const FieldType field_type;
|
||||
// Number of bits after which wrap-around occurs. In most cases,
|
||||
// this should be the number of bits in the field data type, i.e.
|
||||
// 8 for an uint8_t, 32 for a int32_t and so on. However, `value_width`
|
||||
// can be used to achieve a more efficient encoding if it is known
|
||||
// that the field uses a smaller number of bits. For example, a
|
||||
// 15-bit counter could set `value_width` to 15 even if the data is
|
||||
// actually stored in a uint32_t.
|
||||
const uint64_t value_width;
|
||||
// Field ID 0 is reserved for timestamps.
|
||||
static constexpr uint64_t kTimestampField = 0;
|
||||
};
|
||||
|
||||
// The EventEncoder is used to encode a batch of events.
|
||||
class EventEncoder {
|
||||
public:
|
||||
EventEncoder(EventParameters params, rtc::ArrayView<const RtcEvent*> batch);
|
||||
|
||||
void EncodeField(const FieldParameters& params,
|
||||
const std::vector<uint64_t>& values,
|
||||
const std::vector<bool>* positions = nullptr);
|
||||
|
||||
void EncodeField(const FieldParameters& params,
|
||||
const ValuesWithPositions& values);
|
||||
|
||||
void EncodeField(const FieldParameters& params,
|
||||
const std::vector<absl::string_view>& values);
|
||||
|
||||
std::string AsString();
|
||||
|
||||
private:
|
||||
size_t batch_size_;
|
||||
uint32_t event_tag_;
|
||||
std::vector<std::string> encoded_fields_;
|
||||
};
|
||||
|
||||
std::string EncodeSingleValue(uint64_t value, FieldType field_type);
|
||||
std::string EncodeDeltasV3(FixedLengthEncodingParametersV3 params,
|
||||
uint64_t base,
|
||||
rtc::ArrayView<const uint64_t> values);
|
||||
|
||||
// Given a batch of RtcEvents and a member pointer, extract that
|
||||
// member from each event in the batch. Signed integer members are
|
||||
// encoded as unsigned, and the bitsize increased so the result can
|
||||
// represented as a std::vector<uint64_t>.
|
||||
// This is intended to be used in conjuction with
|
||||
// EventEncoder::EncodeField to encode a batch of events as follows:
|
||||
// auto values = ExtractRtcEventMember(batch, RtcEventFoo::timestamp_ms);
|
||||
// encoder.EncodeField(timestamp_params, values)
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_integral<T>::value, bool> = true>
|
||||
std::vector<uint64_t> ExtractRtcEventMember(
|
||||
rtc::ArrayView<const RtcEvent*> batch,
|
||||
const T E::*member) {
|
||||
std::vector<uint64_t> values;
|
||||
values.reserve(batch.size());
|
||||
for (const RtcEvent* event : batch) {
|
||||
RTC_CHECK_EQ(event->GetType(), E::kType);
|
||||
T value = static_cast<const E*>(event)->*member;
|
||||
values.push_back(EncodeAsUnsigned(value));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
// Extract an optional field from a batch of RtcEvents.
|
||||
// The function returns a vector of positions in addition to the vector of
|
||||
// values. The vector `positions` has the same length as the batch where
|
||||
// `positions[i] == true` iff the batch[i]->member has a value.
|
||||
// The values vector only contains the values that exists, so it
|
||||
// may be shorter than the batch.
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_integral<T>::value, bool> = true>
|
||||
ValuesWithPositions ExtractRtcEventMember(rtc::ArrayView<const RtcEvent*> batch,
|
||||
const absl::optional<T> E::*member) {
|
||||
ValuesWithPositions result;
|
||||
result.position_mask.reserve(batch.size());
|
||||
result.values.reserve(batch.size());
|
||||
for (const RtcEvent* event : batch) {
|
||||
RTC_CHECK_EQ(event->GetType(), E::kType);
|
||||
absl::optional<T> field = static_cast<const E*>(event)->*member;
|
||||
result.position_mask.push_back(field.has_value());
|
||||
if (field.has_value()) {
|
||||
result.values.push_back(EncodeAsUnsigned(field.value()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Extract an enum field from a batch of RtcEvents.
|
||||
// Requires specializing RtcEventLogEnum<T> for the enum type T.
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_enum<T>::value, bool> = true>
|
||||
std::vector<uint64_t> ExtractRtcEventMember(
|
||||
rtc::ArrayView<const RtcEvent*> batch,
|
||||
const T E::*member) {
|
||||
std::vector<uint64_t> values;
|
||||
values.reserve(batch.size());
|
||||
for (const RtcEvent* event : batch) {
|
||||
RTC_CHECK_EQ(event->GetType(), E::kType);
|
||||
T value = static_cast<const E*>(event)->*member;
|
||||
values.push_back(RtcEventLogEnum<T>::Encode(value));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
// Extract a string field from a batch of RtcEvents.
|
||||
template <typename E>
|
||||
std::vector<absl::string_view> ExtractRtcEventMember(
|
||||
rtc::ArrayView<const RtcEvent*> batch,
|
||||
const std::string E::*member) {
|
||||
std::vector<absl::string_view> values;
|
||||
values.reserve(batch.size());
|
||||
for (const RtcEvent* event : batch) {
|
||||
RTC_CHECK_EQ(event->GetType(), E::kType);
|
||||
absl::string_view str = static_cast<const E*>(event)->*member;
|
||||
values.push_back(str);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_H_
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
|
||||
/*
|
||||
* 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_field_encoding_parser.h"
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "logging/rtc_event_log/encoder/var_int.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
|
||||
#include "rtc_base/bitstream_reader.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace {
|
||||
absl::optional<webrtc::FieldType> ConvertFieldType(uint64_t value) {
|
||||
switch (value) {
|
||||
case static_cast<uint64_t>(webrtc::FieldType::kFixed8):
|
||||
return webrtc::FieldType::kFixed8;
|
||||
case static_cast<uint64_t>(webrtc::FieldType::kFixed32):
|
||||
return webrtc::FieldType::kFixed32;
|
||||
case static_cast<uint64_t>(webrtc::FieldType::kFixed64):
|
||||
return webrtc::FieldType::kFixed64;
|
||||
case static_cast<uint64_t>(webrtc::FieldType::kVarInt):
|
||||
return webrtc::FieldType::kVarInt;
|
||||
case static_cast<uint64_t>(webrtc::FieldType::kString):
|
||||
return webrtc::FieldType::kString;
|
||||
default:
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
uint64_t EventParser::ReadLittleEndian(uint8_t bytes) {
|
||||
RTC_DCHECK_LE(bytes, sizeof(uint64_t));
|
||||
RTC_DCHECK_GE(bytes, 1);
|
||||
|
||||
uint64_t value = 0;
|
||||
|
||||
if (bytes > pending_data_.length()) {
|
||||
SetError();
|
||||
return value;
|
||||
}
|
||||
|
||||
const uint8_t* p = reinterpret_cast<const uint8_t*>(pending_data_.data());
|
||||
unsigned int shift = 0;
|
||||
uint8_t remaining = bytes;
|
||||
while (remaining > 0) {
|
||||
value += (static_cast<uint64_t>(*p) << shift);
|
||||
shift += 8;
|
||||
++p;
|
||||
--remaining;
|
||||
}
|
||||
|
||||
pending_data_ = pending_data_.substr(bytes);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t EventParser::ReadVarInt() {
|
||||
uint64_t output = 0;
|
||||
bool success;
|
||||
std::tie(success, pending_data_) = DecodeVarInt(pending_data_, &output);
|
||||
if (!success) {
|
||||
SetError();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
uint64_t EventParser::ReadOptionalValuePositions() {
|
||||
RTC_DCHECK(positions_.empty());
|
||||
size_t bits_to_read = NumEventsInBatch();
|
||||
positions_.reserve(bits_to_read);
|
||||
if (pending_data_.size() * 8 < bits_to_read) {
|
||||
SetError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BitstreamReader reader(pending_data_);
|
||||
for (size_t i = 0; i < bits_to_read; i++) {
|
||||
positions_.push_back(reader.ReadBit());
|
||||
}
|
||||
if (!reader.Ok()) {
|
||||
SetError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num_existing_values =
|
||||
std::count(positions_.begin(), positions_.end(), 1);
|
||||
pending_data_ = pending_data_.substr((bits_to_read + 7) / 8);
|
||||
return num_existing_values;
|
||||
}
|
||||
|
||||
uint64_t EventParser::ReadSingleValue(FieldType field_type) {
|
||||
switch (field_type) {
|
||||
case FieldType::kFixed8:
|
||||
return ReadLittleEndian(/*bytes=*/1);
|
||||
case FieldType::kFixed32:
|
||||
return ReadLittleEndian(/*bytes=*/4);
|
||||
case FieldType::kFixed64:
|
||||
return ReadLittleEndian(/*bytes=*/8);
|
||||
case FieldType::kVarInt:
|
||||
return ReadVarInt();
|
||||
case FieldType::kString:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
SetError();
|
||||
return 0;
|
||||
}
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
SetError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EventParser::ReadDeltasAndPopulateValues(
|
||||
FixedLengthEncodingParametersV3 params,
|
||||
uint64_t num_deltas,
|
||||
uint64_t base) {
|
||||
RTC_DCHECK(values_.empty());
|
||||
values_.reserve(num_deltas + 1);
|
||||
values_.push_back(base);
|
||||
|
||||
if (pending_data_.size() * 8 < num_deltas * params.delta_bit_width()) {
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
BitstreamReader reader(pending_data_);
|
||||
const uint64_t top_bit = static_cast<uint64_t>(1)
|
||||
<< (params.delta_bit_width() - 1);
|
||||
|
||||
uint64_t value = base;
|
||||
for (uint64_t i = 0; i < num_deltas; ++i) {
|
||||
uint64_t delta = reader.ReadBits(params.delta_bit_width());
|
||||
RTC_DCHECK_LE(value, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
|
||||
params.value_bit_width()));
|
||||
RTC_DCHECK_LE(delta, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
|
||||
params.delta_bit_width()));
|
||||
bool negative_delta = params.signed_deltas() && ((delta & top_bit) != 0);
|
||||
if (negative_delta) {
|
||||
uint64_t delta_abs = (~delta & params.delta_mask()) + 1;
|
||||
value = (value - delta_abs) & params.value_mask();
|
||||
} else {
|
||||
value = (value + delta) & params.value_mask();
|
||||
}
|
||||
values_.push_back(value);
|
||||
}
|
||||
|
||||
if (!reader.Ok()) {
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
pending_data_ =
|
||||
pending_data_.substr((num_deltas * params.delta_bit_width() + 7) / 8);
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus EventParser::Initialize(absl::string_view s,
|
||||
bool batched) {
|
||||
pending_data_ = s;
|
||||
num_events_ = 1;
|
||||
|
||||
if (batched) {
|
||||
num_events_ = ReadVarInt();
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error(
|
||||
"Failed to read number of events in batch.", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus EventParser::ParseNumericFieldInternal(
|
||||
uint64_t value_bit_width,
|
||||
FieldType field_type) {
|
||||
RTC_DCHECK(values_.empty());
|
||||
RTC_DCHECK(positions_.empty());
|
||||
|
||||
if (num_events_ == 1) {
|
||||
// Just a single value in the batch.
|
||||
uint64_t base = ReadSingleValue(field_type);
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
positions_.push_back(true);
|
||||
values_.push_back(base);
|
||||
} else {
|
||||
// Delta compressed batch.
|
||||
// Read delta header.
|
||||
uint64_t header_value = ReadVarInt();
|
||||
if (!Ok())
|
||||
return RtcEventLogParseStatus::Error("Failed to read delta header",
|
||||
__FILE__, __LINE__);
|
||||
// NB: value_bit_width may be incorrect for the field, if this isn't the
|
||||
// field we are looking for.
|
||||
absl::optional<FixedLengthEncodingParametersV3> delta_header =
|
||||
FixedLengthEncodingParametersV3::ParseDeltaHeader(header_value,
|
||||
value_bit_width);
|
||||
if (!delta_header.has_value()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to parse delta header",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
uint64_t num_existing_deltas = NumEventsInBatch() - 1;
|
||||
if (delta_header->values_optional()) {
|
||||
size_t num_nonempty_values = ReadOptionalValuePositions();
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error(
|
||||
"Failed to read positions of optional values", __FILE__, __LINE__);
|
||||
}
|
||||
if (num_nonempty_values < 1 || NumEventsInBatch() < num_nonempty_values) {
|
||||
return RtcEventLogParseStatus::Error(
|
||||
"Expected at least one non_empty value", __FILE__, __LINE__);
|
||||
}
|
||||
num_existing_deltas = num_nonempty_values - 1;
|
||||
} else {
|
||||
// All elements in the batch have values.
|
||||
positions_.assign(NumEventsInBatch(), 1u);
|
||||
}
|
||||
|
||||
// Read base.
|
||||
uint64_t base = ReadSingleValue(field_type);
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
if (delta_header->values_equal()) {
|
||||
// Duplicate the base value num_existing_deltas times.
|
||||
values_.assign(num_existing_deltas + 1, base);
|
||||
} else {
|
||||
// Read deltas; ceil(num_existing_deltas*delta_width/8) bits
|
||||
ReadDeltasAndPopulateValues(delta_header.value(), num_existing_deltas,
|
||||
base);
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to decode deltas",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus EventParser::ParseStringFieldInternal() {
|
||||
RTC_DCHECK(strings_.empty());
|
||||
if (num_events_ > 1) {
|
||||
// String encoding params reserved for future use.
|
||||
uint64_t encoding_params = ReadVarInt();
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to read string encoding",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
if (encoding_params != 0) {
|
||||
return RtcEventLogParseStatus::Error(
|
||||
"Unrecognized string encoding parameters", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
strings_.reserve(num_events_);
|
||||
for (uint64_t i = 0; i < num_events_; ++i) {
|
||||
// Just a single value in the batch.
|
||||
uint64_t size = ReadVarInt();
|
||||
if (!Ok()) {
|
||||
return RtcEventLogParseStatus::Error("Failed to read string size",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
if (size > pending_data_.size()) {
|
||||
return RtcEventLogParseStatus::Error("String size exceeds remaining data",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
strings_.push_back(pending_data_.substr(0, size));
|
||||
pending_data_ = pending_data_.substr(size);
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
RtcEventLogParseStatus EventParser::ParseField(const FieldParameters& params) {
|
||||
// Verify that the event parses fields in increasing order.
|
||||
if (params.field_id == FieldParameters::kTimestampField) {
|
||||
RTC_DCHECK_EQ(last_field_id_, FieldParameters::kTimestampField);
|
||||
} else {
|
||||
RTC_DCHECK_GT(params.field_id, last_field_id_);
|
||||
}
|
||||
last_field_id_ = params.field_id;
|
||||
|
||||
// Initialization for positional fields that don't encode field ID and type.
|
||||
uint64_t field_id = params.field_id;
|
||||
FieldType field_type = params.field_type;
|
||||
|
||||
// Fields are encoded in increasing field_id order.
|
||||
// Skip unknown fields with field_id < params.field_id until we either
|
||||
// find params.field_id or a field with higher id, in which case we know that
|
||||
// params.field_id doesn't exist.
|
||||
while (!pending_data_.empty()) {
|
||||
absl::string_view field_start = pending_data_;
|
||||
ClearTemporaries();
|
||||
|
||||
// Read tag for non-positional fields.
|
||||
if (params.field_id != FieldParameters::kTimestampField) {
|
||||
uint64_t field_tag = ReadVarInt();
|
||||
if (!Ok())
|
||||
return RtcEventLogParseStatus::Error("Failed to read field tag",
|
||||
__FILE__, __LINE__);
|
||||
// Split tag into field ID and field type.
|
||||
field_id = field_tag >> 3;
|
||||
absl::optional<FieldType> conversion = ConvertFieldType(field_tag & 7u);
|
||||
if (!conversion.has_value())
|
||||
return RtcEventLogParseStatus::Error("Failed to parse field type",
|
||||
__FILE__, __LINE__);
|
||||
field_type = conversion.value();
|
||||
}
|
||||
|
||||
if (field_id > params.field_id) {
|
||||
// We've passed all fields with ids less than or equal to what we are
|
||||
// looking for. Reset pending_data_ to first field with id higher than
|
||||
// params.field_id, since we didn't find the field we were looking for.
|
||||
pending_data_ = field_start;
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
if (field_type == FieldType::kString) {
|
||||
auto status = ParseStringFieldInternal();
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
auto status = ParseNumericFieldInternal(params.value_width, field_type);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (field_id == params.field_id) {
|
||||
// The field we're looking for has been found and values populated.
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
}
|
||||
|
||||
// Field not found because the event ended.
|
||||
ClearTemporaries();
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>
|
||||
EventParser::ParseStringField(const FieldParameters& params,
|
||||
bool required_field) {
|
||||
using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>;
|
||||
RTC_DCHECK_EQ(params.field_type, FieldType::kString);
|
||||
auto status = ParseField(params);
|
||||
if (!status.ok())
|
||||
return StatusOr(status);
|
||||
rtc::ArrayView<absl::string_view> strings = GetStrings();
|
||||
if (required_field && strings.size() != NumEventsInBatch()) {
|
||||
return StatusOr::Error("Required string field not found", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
return StatusOr(strings);
|
||||
}
|
||||
|
||||
RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>
|
||||
EventParser::ParseNumericField(const FieldParameters& params,
|
||||
bool required_field) {
|
||||
using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>;
|
||||
RTC_DCHECK_NE(params.field_type, FieldType::kString);
|
||||
auto status = ParseField(params);
|
||||
if (!status.ok())
|
||||
return StatusOr(status);
|
||||
rtc::ArrayView<uint64_t> values = GetValues();
|
||||
if (required_field && values.size() != NumEventsInBatch()) {
|
||||
return StatusOr::Error("Required numerical field not found", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
return StatusOr(values);
|
||||
}
|
||||
|
||||
RtcEventLogParseStatusOr<EventParser::ValueAndPostionView>
|
||||
EventParser::ParseOptionalNumericField(const FieldParameters& params,
|
||||
bool required_field) {
|
||||
using StatusOr = RtcEventLogParseStatusOr<ValueAndPostionView>;
|
||||
RTC_DCHECK_NE(params.field_type, FieldType::kString);
|
||||
auto status = ParseField(params);
|
||||
if (!status.ok())
|
||||
return StatusOr(status);
|
||||
ValueAndPostionView view{GetValues(), GetPositions()};
|
||||
if (required_field && view.positions.size() != NumEventsInBatch()) {
|
||||
return StatusOr::Error("Required numerical field not found", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
return StatusOr(view);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* 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_FIELD_ENCODING_PARSER_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_PARSER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class EventParser {
|
||||
public:
|
||||
struct ValueAndPostionView {
|
||||
rtc::ArrayView<uint64_t> values;
|
||||
rtc::ArrayView<uint8_t> positions;
|
||||
};
|
||||
|
||||
EventParser() = default;
|
||||
|
||||
// N.B: This method stores a abls::string_view into the string to be
|
||||
// parsed. The caller is responsible for ensuring that the actual string
|
||||
// remains unmodified and outlives the EventParser.
|
||||
RtcEventLogParseStatus Initialize(absl::string_view s, bool batched);
|
||||
|
||||
// Attempts to parse the field specified by `params`, skipping past
|
||||
// other fields that may occur before it. If 'required_field == true',
|
||||
// then failing to find the field is an error, otherwise the functions
|
||||
// return success, but with an empty view of values.
|
||||
RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>> ParseStringField(
|
||||
const FieldParameters& params,
|
||||
bool required_field = true);
|
||||
RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> ParseNumericField(
|
||||
const FieldParameters& params,
|
||||
bool required_field = true);
|
||||
RtcEventLogParseStatusOr<ValueAndPostionView> ParseOptionalNumericField(
|
||||
const FieldParameters& params,
|
||||
bool required_field = true);
|
||||
|
||||
// Number of events in a batch.
|
||||
uint64_t NumEventsInBatch() const { return num_events_; }
|
||||
|
||||
// Bytes remaining in `pending_data_`. Assuming there are no unknown
|
||||
// fields, BytesRemaining() should return 0 when all known fields
|
||||
// in the event have been parsed.
|
||||
size_t RemainingBytes() const { return pending_data_.size(); }
|
||||
|
||||
private:
|
||||
uint64_t ReadLittleEndian(uint8_t bytes);
|
||||
uint64_t ReadVarInt();
|
||||
uint64_t ReadSingleValue(FieldType field_type);
|
||||
uint64_t ReadOptionalValuePositions();
|
||||
void ReadDeltasAndPopulateValues(FixedLengthEncodingParametersV3 params,
|
||||
uint64_t num_deltas,
|
||||
uint64_t base);
|
||||
RtcEventLogParseStatus ParseNumericFieldInternal(uint64_t value_bit_width,
|
||||
FieldType field_type);
|
||||
RtcEventLogParseStatus ParseStringFieldInternal();
|
||||
|
||||
// Attempts to parse the field specified by `params`, skipping past
|
||||
// other fields that may occur before it. Returns
|
||||
// RtcEventLogParseStatus::Success() and populates `values_` (and
|
||||
// `positions_`) if the field is found. Returns
|
||||
// RtcEventLogParseStatus::Success() and clears `values_` (and `positions_`)
|
||||
// if the field doesn't exist. Returns a RtcEventLogParseStatus::Error() if
|
||||
// the log is incomplete, malformed or otherwise can't be parsed.
|
||||
RtcEventLogParseStatus ParseField(const FieldParameters& params);
|
||||
|
||||
void SetError() { error_ = true; }
|
||||
bool Ok() const { return !error_; }
|
||||
|
||||
rtc::ArrayView<uint64_t> GetValues() { return values_; }
|
||||
rtc::ArrayView<uint8_t> GetPositions() { return positions_; }
|
||||
rtc::ArrayView<absl::string_view> GetStrings() { return strings_; }
|
||||
|
||||
void ClearTemporaries() {
|
||||
positions_.clear();
|
||||
values_.clear();
|
||||
strings_.clear();
|
||||
}
|
||||
|
||||
// Tracks whether an error has occurred in one of the helper
|
||||
// functions above.
|
||||
bool error_ = false;
|
||||
|
||||
// Temporary storage for result.
|
||||
std::vector<uint8_t> positions_;
|
||||
std::vector<uint64_t> values_;
|
||||
std::vector<absl::string_view> strings_;
|
||||
|
||||
// String to be consumed.
|
||||
absl::string_view pending_data_;
|
||||
uint64_t num_events_ = 1;
|
||||
uint64_t last_field_id_ = FieldParameters::kTimestampField;
|
||||
};
|
||||
|
||||
// Inverse of the ExtractRtcEventMember function used when parsing
|
||||
// a log. Uses a vector of values to populate a specific field in a
|
||||
// vector of structs.
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_integral<T>::value, bool> = true>
|
||||
ABSL_MUST_USE_RESULT RtcEventLogParseStatus
|
||||
PopulateRtcEventMember(const rtc::ArrayView<uint64_t> values,
|
||||
T E::*member,
|
||||
rtc::ArrayView<E> output) {
|
||||
size_t batch_size = values.size();
|
||||
RTC_CHECK_EQ(output.size(), batch_size);
|
||||
for (size_t i = 0; i < batch_size; ++i) {
|
||||
output[i].*member = DecodeFromUnsignedToType<T>(values[i]);
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
// Same as above, but for optional fields.
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_integral<T>::value, bool> = true>
|
||||
ABSL_MUST_USE_RESULT RtcEventLogParseStatus
|
||||
PopulateRtcEventMember(const rtc::ArrayView<uint8_t> positions,
|
||||
const rtc::ArrayView<uint64_t> values,
|
||||
absl::optional<T> E::*member,
|
||||
rtc::ArrayView<E> output) {
|
||||
size_t batch_size = positions.size();
|
||||
RTC_CHECK_EQ(output.size(), batch_size);
|
||||
RTC_CHECK_LE(values.size(), batch_size);
|
||||
auto value_it = values.begin();
|
||||
for (size_t i = 0; i < batch_size; ++i) {
|
||||
if (positions[i]) {
|
||||
RTC_CHECK(value_it != values.end());
|
||||
output[i].*member = DecodeFromUnsignedToType<T>(value_it);
|
||||
++value_it;
|
||||
} else {
|
||||
output[i].*member = absl::nullopt;
|
||||
}
|
||||
}
|
||||
RTC_CHECK(value_it == values.end());
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
// Same as above, but for enum fields.
|
||||
template <typename T,
|
||||
typename E,
|
||||
std::enable_if_t<std::is_enum<T>::value, bool> = true>
|
||||
ABSL_MUST_USE_RESULT RtcEventLogParseStatus
|
||||
PopulateRtcEventMember(const rtc::ArrayView<uint64_t> values,
|
||||
T E::*member,
|
||||
rtc::ArrayView<E> output) {
|
||||
size_t batch_size = values.size();
|
||||
RTC_CHECK_EQ(output.size(), batch_size);
|
||||
for (size_t i = 0; i < batch_size; ++i) {
|
||||
auto result = RtcEventLogEnum<T>::Decode(values[i]);
|
||||
if (!result.ok()) {
|
||||
return result.status();
|
||||
}
|
||||
output[i].*member = result.value();
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
// Same as above, but for string fields.
|
||||
template <typename E>
|
||||
ABSL_MUST_USE_RESULT RtcEventLogParseStatus
|
||||
PopulateRtcEventMember(const rtc::ArrayView<absl::string_view> values,
|
||||
std::string E::*member,
|
||||
rtc::ArrayView<E> output) {
|
||||
size_t batch_size = values.size();
|
||||
RTC_CHECK_EQ(output.size(), batch_size);
|
||||
for (size_t i = 0; i < batch_size; ++i) {
|
||||
output[i].*member = values[i];
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
// Same as above, but for Timestamp fields.
|
||||
// N.B. Assumes that the encoded value uses millisecond precision.
|
||||
template <typename E>
|
||||
ABSL_MUST_USE_RESULT RtcEventLogParseStatus
|
||||
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]));
|
||||
}
|
||||
return RtcEventLogParseStatus::Success();
|
||||
}
|
||||
|
||||
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_ENCODING_PARSER_H_
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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_field_extraction.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc_event_logging {
|
||||
|
||||
// The bitwidth required to encode values in the range
|
||||
// [0, `max_pos_magnitude`] using an unsigned representation.
|
||||
uint8_t UnsignedBitWidth(uint64_t max_magnitude) {
|
||||
uint8_t required_bits = 1;
|
||||
while (max_magnitude >>= 1) {
|
||||
++required_bits;
|
||||
}
|
||||
return required_bits;
|
||||
}
|
||||
|
||||
// The bitwidth required to encode signed values in the range
|
||||
// [-`max_neg_magnitude`, `max_pos_magnitude`] using a signed
|
||||
// 2-complement representation.
|
||||
uint8_t SignedBitWidth(uint64_t max_pos_magnitude, uint64_t max_neg_magnitude) {
|
||||
const uint8_t bitwidth_positive =
|
||||
max_pos_magnitude > 0 ? UnsignedBitWidth(max_pos_magnitude) : 0;
|
||||
const uint8_t bitwidth_negative =
|
||||
(max_neg_magnitude > 1) ? UnsignedBitWidth(max_neg_magnitude - 1) : 0;
|
||||
return 1 + std::max(bitwidth_positive, bitwidth_negative);
|
||||
}
|
||||
|
||||
// Return the maximum integer of a given bit width.
|
||||
uint64_t MaxUnsignedValueOfBitWidth(uint64_t bit_width) {
|
||||
RTC_DCHECK_GE(bit_width, 1);
|
||||
RTC_DCHECK_LE(bit_width, 64);
|
||||
return (bit_width == 64) ? std::numeric_limits<uint64_t>::max()
|
||||
: ((static_cast<uint64_t>(1) << bit_width) - 1);
|
||||
}
|
||||
|
||||
// Computes the delta between `previous` and `current`, under the assumption
|
||||
// that `bit_mask` is the largest value before wrap-around occurs. The bitmask
|
||||
// must be of the form 2^x-1. (We use the wrap-around to more efficiently
|
||||
// compress counters that wrap around at different bit widths than the
|
||||
// backing C++ data type.)
|
||||
uint64_t UnsignedDelta(uint64_t previous, uint64_t current, uint64_t bit_mask) {
|
||||
RTC_DCHECK_LE(previous, bit_mask);
|
||||
RTC_DCHECK_LE(current, bit_mask);
|
||||
return (current - previous) & bit_mask;
|
||||
}
|
||||
|
||||
} // namespace webrtc_event_logging
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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_FIELD_EXTRACTION_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
|
||||
namespace webrtc_event_logging {
|
||||
uint8_t UnsignedBitWidth(uint64_t max_magnitude);
|
||||
uint8_t SignedBitWidth(uint64_t max_pos_magnitude, uint64_t max_neg_magnitude);
|
||||
uint64_t MaxUnsignedValueOfBitWidth(uint64_t bit_width);
|
||||
uint64_t UnsignedDelta(uint64_t previous, uint64_t current, uint64_t bit_mask);
|
||||
} // namespace webrtc_event_logging
|
||||
|
||||
namespace webrtc {
|
||||
template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
|
||||
uint64_t EncodeAsUnsigned(T value) {
|
||||
return webrtc_event_logging::ToUnsigned(value);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_unsigned<T>::value, bool> = true>
|
||||
uint64_t EncodeAsUnsigned(T value) {
|
||||
return static_cast<uint64_t>(value);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
|
||||
T DecodeFromUnsignedToType(uint64_t value) {
|
||||
T signed_value = 0;
|
||||
bool success = webrtc_event_logging::ToSigned<T>(value, &signed_value);
|
||||
if (!success) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to convert " << value << "to signed type.";
|
||||
// TODO(terelius): Propagate error?
|
||||
}
|
||||
return signed_value;
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_unsigned<T>::value, bool> = true>
|
||||
T DecodeFromUnsignedToType(uint64_t value) {
|
||||
// TODO(terelius): Check range?
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
// RtcEventLogEnum<T> defines a mapping between an enum T
|
||||
// and the event log encodings. To log a new enum type T,
|
||||
// specialize RtcEventLogEnum<T> and add static methods
|
||||
// static uint64_t Encode(T x) {}
|
||||
// static RtcEventLogParseStatusOr<T> Decode(uint64_t x) {}
|
||||
template <typename T>
|
||||
class RtcEventLogEnum {
|
||||
static_assert(sizeof(T) != sizeof(T),
|
||||
"Missing specialisation of RtcEventLogEnum for type");
|
||||
};
|
||||
|
||||
// Represents a vector<optional<uint64_t>> optional_values
|
||||
// as a bit-vector `position_mask` which identifies the positions
|
||||
// of existing values, and a (potentially shorter)
|
||||
// `vector<uint64_t> values` containing the actual values.
|
||||
// The bit vector is constructed such that position_mask[i]
|
||||
// is true iff optional_values[i] has a value, and `values.size()`
|
||||
// is equal to the number of set bits in `position_mask`.
|
||||
struct ValuesWithPositions {
|
||||
std::vector<bool> position_mask;
|
||||
std::vector<uint64_t> values;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_frame_decoded.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventFrameDecoded::RtcEventFrameDecoded(int64_t render_time_ms,
|
||||
uint32_t ssrc,
|
||||
int width,
|
||||
int height,
|
||||
VideoCodecType codec,
|
||||
uint8_t qp)
|
||||
: render_time_ms_(render_time_ms),
|
||||
ssrc_(ssrc),
|
||||
width_(width),
|
||||
height_(height),
|
||||
codec_(codec),
|
||||
qp_(qp) {}
|
||||
|
||||
RtcEventFrameDecoded::RtcEventFrameDecoded(const RtcEventFrameDecoded& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
render_time_ms_(other.render_time_ms_),
|
||||
ssrc_(other.ssrc_),
|
||||
width_(other.width_),
|
||||
height_(other.height_),
|
||||
codec_(other.codec_),
|
||||
qp_(other.qp_) {}
|
||||
|
||||
std::unique_ptr<RtcEventFrameDecoded> RtcEventFrameDecoded::Copy() const {
|
||||
return absl::WrapUnique<RtcEventFrameDecoded>(
|
||||
new RtcEventFrameDecoded(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_FRAME_DECODED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FRAME_DECODED_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "api/video/video_codec_type.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedFrameDecoded {
|
||||
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();
|
||||
int64_t render_time_ms;
|
||||
uint32_t ssrc;
|
||||
int width;
|
||||
int height;
|
||||
VideoCodecType codec;
|
||||
uint8_t qp;
|
||||
};
|
||||
|
||||
class RtcEventFrameDecoded final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::FrameDecoded;
|
||||
|
||||
RtcEventFrameDecoded(int64_t render_time_ms,
|
||||
uint32_t ssrc,
|
||||
int width,
|
||||
int height,
|
||||
VideoCodecType codec,
|
||||
uint8_t qp);
|
||||
~RtcEventFrameDecoded() override = default;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventFrameDecoded> Copy() const;
|
||||
|
||||
int64_t render_time_ms() const { return render_time_ms_; }
|
||||
uint32_t ssrc() const { return ssrc_; }
|
||||
int width() const { return width_; }
|
||||
int height() const { return height_; }
|
||||
VideoCodecType codec() const { return codec_; }
|
||||
uint8_t qp() const { return qp_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::map<uint32_t, std::vector<LoggedFrameDecoded>>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventFrameDecoded(const RtcEventFrameDecoded& other);
|
||||
|
||||
const int64_t render_time_ms_;
|
||||
const uint32_t ssrc_;
|
||||
const int width_;
|
||||
const int height_;
|
||||
const VideoCodecType codec_;
|
||||
const uint8_t qp_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FRAME_DECODED_H_
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_generic_ack_received.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::vector<std::unique_ptr<RtcEventGenericAckReceived>>
|
||||
RtcEventGenericAckReceived::CreateLogs(
|
||||
int64_t packet_number,
|
||||
const std::vector<AckedPacket>& acked_packets) {
|
||||
std::vector<std::unique_ptr<RtcEventGenericAckReceived>> result;
|
||||
int64_t time_us = rtc::TimeMicros();
|
||||
result.reserve(acked_packets.size());
|
||||
for (const AckedPacket& packet : acked_packets) {
|
||||
result.emplace_back(new RtcEventGenericAckReceived(
|
||||
time_us, packet_number, packet.packet_number,
|
||||
packet.receive_acked_packet_time_ms));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RtcEventGenericAckReceived::RtcEventGenericAckReceived(
|
||||
int64_t timestamp_us,
|
||||
int64_t packet_number,
|
||||
int64_t acked_packet_number,
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms)
|
||||
: RtcEvent(timestamp_us),
|
||||
packet_number_(packet_number),
|
||||
acked_packet_number_(acked_packet_number),
|
||||
receive_acked_packet_time_ms_(receive_acked_packet_time_ms) {}
|
||||
|
||||
std::unique_ptr<RtcEventGenericAckReceived> RtcEventGenericAckReceived::Copy()
|
||||
const {
|
||||
return absl::WrapUnique(new RtcEventGenericAckReceived(*this));
|
||||
}
|
||||
|
||||
RtcEventGenericAckReceived::RtcEventGenericAckReceived(
|
||||
const RtcEventGenericAckReceived& packet) = default;
|
||||
|
||||
RtcEventGenericAckReceived::~RtcEventGenericAckReceived() = default;
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_GENERIC_ACK_RECEIVED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_ACK_RECEIVED_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedGenericAckReceived {
|
||||
LoggedGenericAckReceived() = default;
|
||||
LoggedGenericAckReceived(Timestamp timestamp,
|
||||
int64_t packet_number,
|
||||
int64_t acked_packet_number,
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms)
|
||||
: timestamp(timestamp),
|
||||
packet_number(packet_number),
|
||||
acked_packet_number(acked_packet_number),
|
||||
receive_acked_packet_time_ms(receive_acked_packet_time_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();
|
||||
int64_t packet_number;
|
||||
int64_t acked_packet_number;
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms;
|
||||
};
|
||||
|
||||
struct AckedPacket {
|
||||
// The packet number that was acked.
|
||||
int64_t packet_number;
|
||||
|
||||
// The time where the packet was received. Not every ACK will
|
||||
// include the receive timestamp.
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms;
|
||||
};
|
||||
|
||||
class RtcEventGenericAckReceived final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::GenericAckReceived;
|
||||
|
||||
// For a collection of acked packets, it creates a vector of logs to log with
|
||||
// the same timestamp.
|
||||
static std::vector<std::unique_ptr<RtcEventGenericAckReceived>> CreateLogs(
|
||||
int64_t packet_number,
|
||||
const std::vector<AckedPacket>& acked_packets);
|
||||
|
||||
~RtcEventGenericAckReceived() override;
|
||||
|
||||
std::unique_ptr<RtcEventGenericAckReceived> Copy() const;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
// An identifier of the packet which contained an ack.
|
||||
int64_t packet_number() const { return packet_number_; }
|
||||
|
||||
// An identifier of the acked packet.
|
||||
int64_t acked_packet_number() const { return acked_packet_number_; }
|
||||
|
||||
// Timestamp when the `acked_packet_number` was received by the remote side.
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms() const {
|
||||
return receive_acked_packet_time_ms_;
|
||||
}
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedGenericAckReceived>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventGenericAckReceived(const RtcEventGenericAckReceived& packet);
|
||||
|
||||
// When the ack is received, `packet_number` identifies the packet which
|
||||
// contained an ack for `acked_packet_number`, and contains the
|
||||
// `receive_acked_packet_time_ms` on which the `acked_packet_number` was
|
||||
// received on the remote side. The `receive_acked_packet_time_ms` may be
|
||||
// null.
|
||||
RtcEventGenericAckReceived(
|
||||
int64_t timestamp_us,
|
||||
int64_t packet_number,
|
||||
int64_t acked_packet_number,
|
||||
absl::optional<int64_t> receive_acked_packet_time_ms);
|
||||
|
||||
const int64_t packet_number_;
|
||||
const int64_t acked_packet_number_;
|
||||
const absl::optional<int64_t> receive_acked_packet_time_ms_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_ACK_RECEIVED_H_
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_generic_packet_received.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
|
||||
int64_t packet_number,
|
||||
size_t packet_length)
|
||||
: packet_number_(packet_number), packet_length_(packet_length) {}
|
||||
|
||||
RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
|
||||
const RtcEventGenericPacketReceived& packet) = default;
|
||||
|
||||
RtcEventGenericPacketReceived::~RtcEventGenericPacketReceived() = default;
|
||||
|
||||
std::unique_ptr<RtcEventGenericPacketReceived>
|
||||
RtcEventGenericPacketReceived::Copy() const {
|
||||
return absl::WrapUnique(new RtcEventGenericPacketReceived(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_GENERIC_PACKET_RECEIVED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedGenericPacketReceived {
|
||||
LoggedGenericPacketReceived() = default;
|
||||
LoggedGenericPacketReceived(Timestamp timestamp,
|
||||
int64_t packet_number,
|
||||
int packet_length)
|
||||
: timestamp(timestamp),
|
||||
packet_number(packet_number),
|
||||
packet_length(packet_length) {}
|
||||
|
||||
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();
|
||||
int64_t packet_number;
|
||||
int packet_length;
|
||||
};
|
||||
|
||||
class RtcEventGenericPacketReceived final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::GenericPacketReceived;
|
||||
|
||||
RtcEventGenericPacketReceived(int64_t packet_number, size_t packet_length);
|
||||
~RtcEventGenericPacketReceived() override;
|
||||
|
||||
std::unique_ptr<RtcEventGenericPacketReceived> Copy() const;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
// An identifier of the packet.
|
||||
int64_t packet_number() const { return packet_number_; }
|
||||
|
||||
// Total packet length, including all packetization overheads, but not
|
||||
// including ICE/TURN/IP overheads.
|
||||
size_t packet_length() const { return packet_length_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedGenericPacketReceived>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventGenericPacketReceived(const RtcEventGenericPacketReceived& packet);
|
||||
|
||||
const int64_t packet_number_;
|
||||
const size_t packet_length_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_generic_packet_sent.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventGenericPacketSent::RtcEventGenericPacketSent(int64_t packet_number,
|
||||
size_t overhead_length,
|
||||
size_t payload_length,
|
||||
size_t padding_length)
|
||||
: packet_number_(packet_number),
|
||||
overhead_length_(overhead_length),
|
||||
payload_length_(payload_length),
|
||||
padding_length_(padding_length) {}
|
||||
|
||||
RtcEventGenericPacketSent::RtcEventGenericPacketSent(
|
||||
const RtcEventGenericPacketSent& packet) = default;
|
||||
|
||||
RtcEventGenericPacketSent::~RtcEventGenericPacketSent() = default;
|
||||
|
||||
std::unique_ptr<RtcEventGenericPacketSent> RtcEventGenericPacketSent::Copy()
|
||||
const {
|
||||
return absl::WrapUnique(new RtcEventGenericPacketSent(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_GENERIC_PACKET_SENT_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedGenericPacketSent {
|
||||
LoggedGenericPacketSent() = default;
|
||||
LoggedGenericPacketSent(Timestamp timestamp,
|
||||
int64_t packet_number,
|
||||
size_t overhead_length,
|
||||
size_t payload_length,
|
||||
size_t padding_length)
|
||||
: timestamp(timestamp),
|
||||
packet_number(packet_number),
|
||||
overhead_length(overhead_length),
|
||||
payload_length(payload_length),
|
||||
padding_length(padding_length) {}
|
||||
|
||||
int64_t log_time_us() const { return timestamp.us(); }
|
||||
int64_t log_time_ms() const { return timestamp.ms(); }
|
||||
Timestamp log_time() const { return timestamp; }
|
||||
|
||||
size_t packet_length() const {
|
||||
return payload_length + padding_length + overhead_length;
|
||||
}
|
||||
Timestamp timestamp = Timestamp::MinusInfinity();
|
||||
int64_t packet_number;
|
||||
size_t overhead_length;
|
||||
size_t payload_length;
|
||||
size_t padding_length;
|
||||
};
|
||||
|
||||
class RtcEventGenericPacketSent final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::GenericPacketSent;
|
||||
|
||||
RtcEventGenericPacketSent(int64_t packet_number,
|
||||
size_t overhead_length,
|
||||
size_t payload_length,
|
||||
size_t padding_length);
|
||||
~RtcEventGenericPacketSent() override;
|
||||
|
||||
std::unique_ptr<RtcEventGenericPacketSent> Copy() const;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
// An identifier of the packet.
|
||||
int64_t packet_number() const { return packet_number_; }
|
||||
|
||||
// Total packet length, including all packetization overheads, but not
|
||||
// including ICE/TURN/IP overheads.
|
||||
size_t packet_length() const {
|
||||
return overhead_length_ + payload_length_ + padding_length_;
|
||||
}
|
||||
|
||||
// The number of bytes in overhead, including framing overheads, acks if
|
||||
// present, etc.
|
||||
size_t overhead_length() const { return overhead_length_; }
|
||||
|
||||
// Length of payload sent (size of raw audio/video/data), without
|
||||
// packetization overheads. This may still include serialization overheads.
|
||||
size_t payload_length() const { return payload_length_; }
|
||||
|
||||
size_t padding_length() const { return padding_length_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedGenericPacketSent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventGenericPacketSent(const RtcEventGenericPacketSent& packet);
|
||||
|
||||
const int64_t packet_number_;
|
||||
const size_t overhead_length_;
|
||||
const size_t payload_length_;
|
||||
const size_t padding_length_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ice_candidate_pair.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventIceCandidatePair::RtcEventIceCandidatePair(
|
||||
IceCandidatePairEventType type,
|
||||
uint32_t candidate_pair_id,
|
||||
uint32_t transaction_id)
|
||||
: type_(type),
|
||||
candidate_pair_id_(candidate_pair_id),
|
||||
transaction_id_(transaction_id) {}
|
||||
|
||||
RtcEventIceCandidatePair::RtcEventIceCandidatePair(
|
||||
const RtcEventIceCandidatePair& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
type_(other.type_),
|
||||
candidate_pair_id_(other.candidate_pair_id_),
|
||||
transaction_id_(other.transaction_id_) {}
|
||||
|
||||
RtcEventIceCandidatePair::~RtcEventIceCandidatePair() = default;
|
||||
|
||||
std::unique_ptr<RtcEventIceCandidatePair> RtcEventIceCandidatePair::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventIceCandidatePair>(
|
||||
new RtcEventIceCandidatePair(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ICE_CANDIDATE_PAIR_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum class IceCandidatePairEventType {
|
||||
kCheckSent,
|
||||
kCheckReceived,
|
||||
kCheckResponseSent,
|
||||
kCheckResponseReceived,
|
||||
kNumValues,
|
||||
};
|
||||
|
||||
struct LoggedIceCandidatePairEvent {
|
||||
LoggedIceCandidatePairEvent() = default;
|
||||
LoggedIceCandidatePairEvent(Timestamp timestamp,
|
||||
IceCandidatePairEventType type,
|
||||
uint32_t candidate_pair_id,
|
||||
uint32_t transaction_id)
|
||||
: timestamp(timestamp),
|
||||
type(type),
|
||||
candidate_pair_id(candidate_pair_id),
|
||||
transaction_id(transaction_id) {}
|
||||
|
||||
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();
|
||||
IceCandidatePairEventType type;
|
||||
uint32_t candidate_pair_id;
|
||||
uint32_t transaction_id;
|
||||
};
|
||||
|
||||
class RtcEventIceCandidatePair final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::IceCandidatePairEvent;
|
||||
|
||||
RtcEventIceCandidatePair(IceCandidatePairEventType type,
|
||||
uint32_t candidate_pair_id,
|
||||
uint32_t transaction_id);
|
||||
|
||||
~RtcEventIceCandidatePair() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventIceCandidatePair> Copy() const;
|
||||
|
||||
IceCandidatePairEventType type() const { return type_; }
|
||||
uint32_t candidate_pair_id() const { return candidate_pair_id_; }
|
||||
uint32_t transaction_id() const { return transaction_id_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedIceCandidatePairEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventIceCandidatePair(const RtcEventIceCandidatePair& other);
|
||||
|
||||
const IceCandidatePairEventType type_;
|
||||
const uint32_t candidate_pair_id_;
|
||||
const uint32_t transaction_id_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ice_candidate_pair_config.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
IceCandidatePairDescription::IceCandidatePairDescription(
|
||||
IceCandidateType local_candidate_type,
|
||||
IceCandidateType remote_candidate_type)
|
||||
: local_candidate_type(local_candidate_type),
|
||||
remote_candidate_type(remote_candidate_type) {
|
||||
local_relay_protocol = IceCandidatePairProtocol::kUnknown;
|
||||
local_network_type = IceCandidateNetworkType::kUnknown;
|
||||
local_address_family = IceCandidatePairAddressFamily::kUnknown;
|
||||
remote_address_family = IceCandidatePairAddressFamily::kUnknown;
|
||||
candidate_pair_protocol = IceCandidatePairProtocol::kUnknown;
|
||||
}
|
||||
|
||||
IceCandidatePairDescription::IceCandidatePairDescription(
|
||||
const IceCandidatePairDescription& other) {
|
||||
local_candidate_type = other.local_candidate_type;
|
||||
local_relay_protocol = other.local_relay_protocol;
|
||||
local_network_type = other.local_network_type;
|
||||
local_address_family = other.local_address_family;
|
||||
remote_candidate_type = other.remote_candidate_type;
|
||||
remote_address_family = other.remote_address_family;
|
||||
candidate_pair_protocol = other.candidate_pair_protocol;
|
||||
}
|
||||
|
||||
IceCandidatePairDescription::~IceCandidatePairDescription() {}
|
||||
|
||||
RtcEventIceCandidatePairConfig::RtcEventIceCandidatePairConfig(
|
||||
IceCandidatePairConfigType type,
|
||||
uint32_t candidate_pair_id,
|
||||
const IceCandidatePairDescription& candidate_pair_desc)
|
||||
: type_(type),
|
||||
candidate_pair_id_(candidate_pair_id),
|
||||
candidate_pair_desc_(candidate_pair_desc) {}
|
||||
|
||||
RtcEventIceCandidatePairConfig::RtcEventIceCandidatePairConfig(
|
||||
const RtcEventIceCandidatePairConfig& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
type_(other.type_),
|
||||
candidate_pair_id_(other.candidate_pair_id_),
|
||||
candidate_pair_desc_(other.candidate_pair_desc_) {}
|
||||
|
||||
RtcEventIceCandidatePairConfig::~RtcEventIceCandidatePairConfig() = default;
|
||||
|
||||
std::unique_ptr<RtcEventIceCandidatePairConfig>
|
||||
RtcEventIceCandidatePairConfig::Copy() const {
|
||||
return absl::WrapUnique<RtcEventIceCandidatePairConfig>(
|
||||
new RtcEventIceCandidatePairConfig(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/candidate.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum class IceCandidatePairConfigType {
|
||||
kAdded,
|
||||
kUpdated,
|
||||
kDestroyed,
|
||||
kSelected,
|
||||
kNumValues,
|
||||
};
|
||||
|
||||
enum class IceCandidatePairProtocol {
|
||||
kUnknown,
|
||||
kUdp,
|
||||
kTcp,
|
||||
kSsltcp,
|
||||
kTls,
|
||||
kNumValues,
|
||||
};
|
||||
|
||||
enum class IceCandidatePairAddressFamily {
|
||||
kUnknown,
|
||||
kIpv4,
|
||||
kIpv6,
|
||||
kNumValues,
|
||||
};
|
||||
|
||||
enum class IceCandidateNetworkType {
|
||||
kUnknown,
|
||||
kEthernet,
|
||||
kLoopback,
|
||||
kWifi,
|
||||
kVpn,
|
||||
kCellular,
|
||||
kNumValues,
|
||||
};
|
||||
|
||||
struct LoggedIceCandidatePairConfig {
|
||||
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();
|
||||
IceCandidatePairConfigType type;
|
||||
uint32_t candidate_pair_id;
|
||||
IceCandidateType local_candidate_type;
|
||||
IceCandidatePairProtocol local_relay_protocol;
|
||||
IceCandidateNetworkType local_network_type;
|
||||
IceCandidatePairAddressFamily local_address_family;
|
||||
IceCandidateType remote_candidate_type;
|
||||
IceCandidatePairAddressFamily remote_address_family;
|
||||
IceCandidatePairProtocol candidate_pair_protocol;
|
||||
};
|
||||
|
||||
class IceCandidatePairDescription {
|
||||
public:
|
||||
IceCandidatePairDescription(IceCandidateType local_candidate_type,
|
||||
IceCandidateType remote_candidate_type);
|
||||
explicit IceCandidatePairDescription(
|
||||
const IceCandidatePairDescription& other);
|
||||
|
||||
~IceCandidatePairDescription();
|
||||
|
||||
IceCandidateType local_candidate_type;
|
||||
IceCandidatePairProtocol local_relay_protocol;
|
||||
IceCandidateNetworkType local_network_type;
|
||||
IceCandidatePairAddressFamily local_address_family;
|
||||
IceCandidateType remote_candidate_type;
|
||||
IceCandidatePairAddressFamily remote_address_family;
|
||||
IceCandidatePairProtocol candidate_pair_protocol;
|
||||
};
|
||||
|
||||
class RtcEventIceCandidatePairConfig final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::IceCandidatePairConfig;
|
||||
|
||||
RtcEventIceCandidatePairConfig(
|
||||
IceCandidatePairConfigType type,
|
||||
uint32_t candidate_pair_id,
|
||||
const IceCandidatePairDescription& candidate_pair_desc);
|
||||
|
||||
~RtcEventIceCandidatePairConfig() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
// N.B. An ICE config event is not considered an RtcEventLog config event.
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventIceCandidatePairConfig> Copy() const;
|
||||
|
||||
IceCandidatePairConfigType type() const { return type_; }
|
||||
uint32_t candidate_pair_id() const { return candidate_pair_id_; }
|
||||
const IceCandidatePairDescription& candidate_pair_desc() const {
|
||||
return candidate_pair_desc_;
|
||||
}
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedIceCandidatePairConfig>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventIceCandidatePairConfig(const RtcEventIceCandidatePairConfig& other);
|
||||
|
||||
const IceCandidatePairConfigType type_;
|
||||
const uint32_t candidate_pair_id_;
|
||||
const IceCandidatePairDescription candidate_pair_desc_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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_LOG_PARSE_STATUS_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_LOG_PARSE_STATUS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
#define RTC_PARSE_RETURN_ERROR(X) \
|
||||
do { \
|
||||
return RtcEventLogParseStatus::Error(#X, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN(X) \
|
||||
do { \
|
||||
if (!(X)) \
|
||||
return RtcEventLogParseStatus::Error(#X, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_MESSAGE(X, M) \
|
||||
do { \
|
||||
if (!(X)) \
|
||||
return RtcEventLogParseStatus::Error((M), __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_OP(OP, X, Y) \
|
||||
do { \
|
||||
if (!((X)OP(Y))) \
|
||||
return RtcEventLogParseStatus::Error(#X #OP #Y, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_EQ(X, Y) \
|
||||
RTC_PARSE_CHECK_OR_RETURN_OP(==, X, Y)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_NE(X, Y) \
|
||||
RTC_PARSE_CHECK_OR_RETURN_OP(!=, X, Y)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_LT(X, Y) RTC_PARSE_CHECK_OR_RETURN_OP(<, X, Y)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_LE(X, Y) \
|
||||
RTC_PARSE_CHECK_OR_RETURN_OP(<=, X, Y)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_GT(X, Y) RTC_PARSE_CHECK_OR_RETURN_OP(>, X, Y)
|
||||
|
||||
#define RTC_PARSE_CHECK_OR_RETURN_GE(X, Y) \
|
||||
RTC_PARSE_CHECK_OR_RETURN_OP(>=, X, Y)
|
||||
|
||||
#define RTC_PARSE_WARN_AND_RETURN_SUCCESS_IF(X, M) \
|
||||
do { \
|
||||
if (X) { \
|
||||
RTC_LOG(LS_WARNING) << (M); \
|
||||
return RtcEventLogParseStatus::Success(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RTC_RETURN_IF_ERROR(X) \
|
||||
do { \
|
||||
const RtcEventLogParseStatus _rtc_parse_status(X); \
|
||||
if (!_rtc_parse_status.ok()) { \
|
||||
return _rtc_parse_status; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// TODO(terelius): Compared to a generic 'Status' class, this
|
||||
// class allows us additional information about the context
|
||||
// in which the error occurred. This is currently limited to
|
||||
// the source location (file and line), but we plan on adding
|
||||
// information about the event and field name being parsed.
|
||||
// If/when we start using absl::Status in WebRTC, consider
|
||||
// whether payloads would be an appropriate alternative.
|
||||
class RtcEventLogParseStatus {
|
||||
template <typename T>
|
||||
friend class RtcEventLogParseStatusOr;
|
||||
|
||||
public:
|
||||
static RtcEventLogParseStatus Success() { return RtcEventLogParseStatus(); }
|
||||
static RtcEventLogParseStatus Error(absl::string_view error,
|
||||
absl::string_view file,
|
||||
int line) {
|
||||
return RtcEventLogParseStatus(error, file, line);
|
||||
}
|
||||
|
||||
bool ok() const { return error_.empty(); }
|
||||
ABSL_DEPRECATED("Use ok() instead") explicit operator bool() const {
|
||||
return ok();
|
||||
}
|
||||
|
||||
std::string message() const { return error_; }
|
||||
|
||||
private:
|
||||
RtcEventLogParseStatus() : error_() {}
|
||||
RtcEventLogParseStatus(absl::string_view error,
|
||||
absl::string_view file,
|
||||
int line)
|
||||
: error_(std::string(error) + " (" + std::string(file) + ": " +
|
||||
std::to_string(line) + ")") {}
|
||||
|
||||
std::string error_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RtcEventLogParseStatusOr {
|
||||
public:
|
||||
RtcEventLogParseStatusOr(RtcEventLogParseStatus status) // NOLINT
|
||||
: status_(status), 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_;
|
||||
}
|
||||
|
||||
T& value() {
|
||||
RTC_DCHECK(ok());
|
||||
return value_;
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatusOr Error(absl::string_view error,
|
||||
absl::string_view file,
|
||||
int line) {
|
||||
return RtcEventLogParseStatusOr(error, file, line);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventLogParseStatusOr() : status_() {}
|
||||
RtcEventLogParseStatusOr(absl::string_view error,
|
||||
absl::string_view file,
|
||||
int line)
|
||||
: status_(error, file, line), value_() {}
|
||||
|
||||
RtcEventLogParseStatus status_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_LOG_PARSE_STATUS_H_
|
||||
|
|
@ -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_
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_probe_cluster_created.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventProbeClusterCreated::RtcEventProbeClusterCreated(int32_t id,
|
||||
int32_t bitrate_bps,
|
||||
uint32_t min_probes,
|
||||
uint32_t min_bytes)
|
||||
: id_(id),
|
||||
bitrate_bps_(bitrate_bps),
|
||||
min_probes_(min_probes),
|
||||
min_bytes_(min_bytes) {}
|
||||
|
||||
RtcEventProbeClusterCreated::RtcEventProbeClusterCreated(
|
||||
const RtcEventProbeClusterCreated& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
id_(other.id_),
|
||||
bitrate_bps_(other.bitrate_bps_),
|
||||
min_probes_(other.min_probes_),
|
||||
min_bytes_(other.min_bytes_) {}
|
||||
|
||||
std::unique_ptr<RtcEventProbeClusterCreated> RtcEventProbeClusterCreated::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventProbeClusterCreated>(
|
||||
new RtcEventProbeClusterCreated(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_PROBE_CLUSTER_CREATED_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedBweProbeClusterCreatedEvent {
|
||||
LoggedBweProbeClusterCreatedEvent() = default;
|
||||
LoggedBweProbeClusterCreatedEvent(Timestamp timestamp,
|
||||
int32_t id,
|
||||
int32_t bitrate_bps,
|
||||
uint32_t min_packets,
|
||||
uint32_t min_bytes)
|
||||
: timestamp(timestamp),
|
||||
id(id),
|
||||
bitrate_bps(bitrate_bps),
|
||||
min_packets(min_packets),
|
||||
min_bytes(min_bytes) {}
|
||||
|
||||
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();
|
||||
int32_t id;
|
||||
int32_t bitrate_bps;
|
||||
uint32_t min_packets;
|
||||
uint32_t min_bytes;
|
||||
};
|
||||
|
||||
class RtcEventProbeClusterCreated final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::ProbeClusterCreated;
|
||||
|
||||
RtcEventProbeClusterCreated(int32_t id,
|
||||
int32_t bitrate_bps,
|
||||
uint32_t min_probes,
|
||||
uint32_t min_bytes);
|
||||
~RtcEventProbeClusterCreated() override = default;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventProbeClusterCreated> Copy() const;
|
||||
|
||||
int32_t id() const { return id_; }
|
||||
int32_t bitrate_bps() const { return bitrate_bps_; }
|
||||
uint32_t min_probes() const { return min_probes_; }
|
||||
uint32_t min_bytes() const { return min_bytes_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedBweProbeClusterCreatedEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventProbeClusterCreated(const RtcEventProbeClusterCreated& other);
|
||||
|
||||
const int32_t id_;
|
||||
const int32_t bitrate_bps_;
|
||||
const uint32_t min_probes_;
|
||||
const uint32_t min_bytes_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_probe_result_failure.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventProbeResultFailure::RtcEventProbeResultFailure(
|
||||
int32_t id,
|
||||
ProbeFailureReason failure_reason)
|
||||
: id_(id), failure_reason_(failure_reason) {}
|
||||
|
||||
RtcEventProbeResultFailure::RtcEventProbeResultFailure(
|
||||
const RtcEventProbeResultFailure& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
id_(other.id_),
|
||||
failure_reason_(other.failure_reason_) {}
|
||||
|
||||
std::unique_ptr<RtcEventProbeResultFailure> RtcEventProbeResultFailure::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventProbeResultFailure>(
|
||||
new RtcEventProbeResultFailure(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_PROBE_RESULT_FAILURE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum class ProbeFailureReason {
|
||||
kInvalidSendReceiveInterval = 0,
|
||||
kInvalidSendReceiveRatio,
|
||||
kTimeout,
|
||||
kLast
|
||||
};
|
||||
|
||||
struct LoggedBweProbeFailureEvent {
|
||||
LoggedBweProbeFailureEvent() = default;
|
||||
LoggedBweProbeFailureEvent(Timestamp timestamp,
|
||||
int32_t id,
|
||||
ProbeFailureReason failure_reason)
|
||||
: timestamp(timestamp), id(id), failure_reason(failure_reason) {}
|
||||
|
||||
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();
|
||||
int32_t id;
|
||||
ProbeFailureReason failure_reason;
|
||||
};
|
||||
|
||||
class RtcEventProbeResultFailure final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::ProbeResultFailure;
|
||||
|
||||
RtcEventProbeResultFailure(int32_t id, ProbeFailureReason failure_reason);
|
||||
~RtcEventProbeResultFailure() override = default;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventProbeResultFailure> Copy() const;
|
||||
|
||||
int32_t id() const { return id_; }
|
||||
ProbeFailureReason failure_reason() const { return failure_reason_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedBweProbeFailureEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventProbeResultFailure(const RtcEventProbeResultFailure& other);
|
||||
|
||||
const int32_t id_;
|
||||
const ProbeFailureReason failure_reason_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_probe_result_success.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventProbeResultSuccess::RtcEventProbeResultSuccess(int32_t id,
|
||||
int32_t bitrate_bps)
|
||||
: id_(id), bitrate_bps_(bitrate_bps) {}
|
||||
|
||||
RtcEventProbeResultSuccess::RtcEventProbeResultSuccess(
|
||||
const RtcEventProbeResultSuccess& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
id_(other.id_),
|
||||
bitrate_bps_(other.bitrate_bps_) {}
|
||||
|
||||
std::unique_ptr<RtcEventProbeResultSuccess> RtcEventProbeResultSuccess::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventProbeResultSuccess>(
|
||||
new RtcEventProbeResultSuccess(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_PROBE_RESULT_SUCCESS_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedBweProbeSuccessEvent {
|
||||
LoggedBweProbeSuccessEvent() = default;
|
||||
LoggedBweProbeSuccessEvent(Timestamp timestamp,
|
||||
int32_t id,
|
||||
int32_t bitrate_bps)
|
||||
: timestamp(timestamp), id(id), bitrate_bps(bitrate_bps) {}
|
||||
|
||||
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();
|
||||
int32_t id;
|
||||
int32_t bitrate_bps;
|
||||
};
|
||||
|
||||
class RtcEventProbeResultSuccess final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::ProbeResultSuccess;
|
||||
|
||||
RtcEventProbeResultSuccess(int32_t id, int32_t bitrate_bps);
|
||||
~RtcEventProbeResultSuccess() override = default;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventProbeResultSuccess> Copy() const;
|
||||
|
||||
int32_t id() const { return id_; }
|
||||
int32_t bitrate_bps() const { return bitrate_bps_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedBweProbeSuccessEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventProbeResultSuccess(const RtcEventProbeResultSuccess& other);
|
||||
|
||||
const int32_t id_;
|
||||
const int32_t bitrate_bps_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_REMOTE_ESTIMATE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedRemoteEstimateEvent {
|
||||
LoggedRemoteEstimateEvent() = default;
|
||||
|
||||
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();
|
||||
absl::optional<DataRate> link_capacity_lower;
|
||||
absl::optional<DataRate> link_capacity_upper;
|
||||
};
|
||||
|
||||
class RtcEventRemoteEstimate final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RemoteEstimateEvent;
|
||||
|
||||
RtcEventRemoteEstimate(DataRate link_capacity_lower,
|
||||
DataRate link_capacity_upper)
|
||||
: link_capacity_lower_(link_capacity_lower),
|
||||
link_capacity_upper_(link_capacity_upper) {}
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedRemoteEstimateEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
const DataRate link_capacity_lower_;
|
||||
const DataRate link_capacity_upper_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_route_change.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventRouteChange::RtcEventRouteChange(bool connected, uint32_t overhead)
|
||||
: connected_(connected), overhead_(overhead) {}
|
||||
|
||||
RtcEventRouteChange::RtcEventRouteChange(const RtcEventRouteChange& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
connected_(other.connected_),
|
||||
overhead_(other.overhead_) {}
|
||||
|
||||
RtcEventRouteChange::~RtcEventRouteChange() = default;
|
||||
|
||||
std::unique_ptr<RtcEventRouteChange> RtcEventRouteChange::Copy() const {
|
||||
return absl::WrapUnique<RtcEventRouteChange>(new RtcEventRouteChange(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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_ROUTE_CHANGE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ROUTE_CHANGE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedRouteChangeEvent {
|
||||
LoggedRouteChangeEvent() = default;
|
||||
LoggedRouteChangeEvent(Timestamp timestamp, bool connected, uint32_t overhead)
|
||||
: timestamp(timestamp), connected(connected), overhead(overhead) {}
|
||||
|
||||
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();
|
||||
bool connected;
|
||||
uint32_t overhead;
|
||||
};
|
||||
|
||||
class RtcEventRouteChange final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RouteChangeEvent;
|
||||
|
||||
RtcEventRouteChange(bool connected, uint32_t overhead);
|
||||
~RtcEventRouteChange() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventRouteChange> Copy() const;
|
||||
|
||||
bool connected() const { return connected_; }
|
||||
uint32_t overhead() const { return overhead_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedRouteChangeEvent>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventRouteChange(const RtcEventRouteChange& other);
|
||||
|
||||
const bool connected_;
|
||||
const uint32_t overhead_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ROUTE_CHANGE_H_
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_rtcp_packet_incoming.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventRtcpPacketIncoming::RtcEventRtcpPacketIncoming(
|
||||
rtc::ArrayView<const uint8_t> packet)
|
||||
: packet_(packet.data(), packet.size()) {}
|
||||
|
||||
RtcEventRtcpPacketIncoming::RtcEventRtcpPacketIncoming(
|
||||
const RtcEventRtcpPacketIncoming& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
packet_(other.packet_.data(), other.packet_.size()) {}
|
||||
|
||||
RtcEventRtcpPacketIncoming::~RtcEventRtcpPacketIncoming() = default;
|
||||
|
||||
std::unique_ptr<RtcEventRtcpPacketIncoming> RtcEventRtcpPacketIncoming::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventRtcpPacketIncoming>(
|
||||
new RtcEventRtcpPacketIncoming(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_RTCP_PACKET_INCOMING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_
|
||||
|
||||
#include <stdint.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 "logging/rtc_event_log/events/logged_rtp_rtcp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtcEventRtcpPacketIncoming final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RtcpPacketIncoming;
|
||||
|
||||
explicit RtcEventRtcpPacketIncoming(rtc::ArrayView<const uint8_t> packet);
|
||||
~RtcEventRtcpPacketIncoming() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventRtcpPacketIncoming> Copy() const;
|
||||
|
||||
const rtc::Buffer& packet() const { return packet_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedRtcpPacketIncoming>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventRtcpPacketIncoming(const RtcEventRtcpPacketIncoming& other);
|
||||
|
||||
rtc::Buffer packet_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_rtcp_packet_outgoing.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventRtcpPacketOutgoing::RtcEventRtcpPacketOutgoing(
|
||||
rtc::ArrayView<const uint8_t> packet)
|
||||
: packet_(packet.data(), packet.size()) {}
|
||||
|
||||
RtcEventRtcpPacketOutgoing::RtcEventRtcpPacketOutgoing(
|
||||
const RtcEventRtcpPacketOutgoing& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
packet_(other.packet_.data(), other.packet_.size()) {}
|
||||
|
||||
RtcEventRtcpPacketOutgoing::~RtcEventRtcpPacketOutgoing() = default;
|
||||
|
||||
std::unique_ptr<RtcEventRtcpPacketOutgoing> RtcEventRtcpPacketOutgoing::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventRtcpPacketOutgoing>(
|
||||
new RtcEventRtcpPacketOutgoing(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_RTCP_PACKET_OUTGOING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_
|
||||
|
||||
#include <stdint.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 "logging/rtc_event_log/events/logged_rtp_rtcp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtcEventRtcpPacketOutgoing final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RtcpPacketOutgoing;
|
||||
|
||||
explicit RtcEventRtcpPacketOutgoing(rtc::ArrayView<const uint8_t> packet);
|
||||
~RtcEventRtcpPacketOutgoing() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventRtcpPacketOutgoing> Copy() const;
|
||||
|
||||
const rtc::Buffer& packet() const { return packet_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedRtcpPacketOutgoing>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing& other);
|
||||
|
||||
rtc::Buffer packet_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_rtp_packet_incoming.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming(
|
||||
const RtpPacketReceived& packet)
|
||||
: packet_(packet) {}
|
||||
|
||||
RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming(
|
||||
const RtcEventRtpPacketIncoming& other)
|
||||
: RtcEvent(other.timestamp_us_), packet_(other.packet_) {}
|
||||
|
||||
RtcEventRtpPacketIncoming::~RtcEventRtpPacketIncoming() = default;
|
||||
|
||||
std::unique_ptr<RtcEventRtpPacketIncoming> RtcEventRtpPacketIncoming::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventRtpPacketIncoming>(
|
||||
new RtcEventRtpPacketIncoming(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_RTP_PACKET_INCOMING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtpPacketReceived;
|
||||
|
||||
class RtcEventRtpPacketIncoming final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RtpPacketIncoming;
|
||||
|
||||
explicit RtcEventRtpPacketIncoming(const RtpPacketReceived& packet);
|
||||
~RtcEventRtpPacketIncoming() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventRtpPacketIncoming> Copy() const;
|
||||
|
||||
size_t packet_length() const { return packet_.size(); }
|
||||
|
||||
rtc::ArrayView<const uint8_t> RawHeader() const {
|
||||
return rtc::MakeArrayView(packet_.data(), header_length());
|
||||
}
|
||||
uint32_t Ssrc() const { return packet_.Ssrc(); }
|
||||
uint32_t Timestamp() const { return packet_.Timestamp(); }
|
||||
uint16_t SequenceNumber() const { return packet_.SequenceNumber(); }
|
||||
uint8_t PayloadType() const { return packet_.PayloadType(); }
|
||||
bool Marker() const { return packet_.Marker(); }
|
||||
template <typename ExtensionTrait, typename... Args>
|
||||
bool GetExtension(Args&&... args) const {
|
||||
return packet_.GetExtension<ExtensionTrait>(std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename ExtensionTrait>
|
||||
rtc::ArrayView<const uint8_t> GetRawExtension() const {
|
||||
return packet_.GetRawExtension<ExtensionTrait>();
|
||||
}
|
||||
template <typename ExtensionTrait>
|
||||
bool HasExtension() const {
|
||||
return packet_.HasExtension<ExtensionTrait>();
|
||||
}
|
||||
|
||||
size_t payload_length() const { return packet_.payload_size(); }
|
||||
size_t header_length() const { return packet_.headers_size(); }
|
||||
size_t padding_length() const { return packet_.padding_size(); }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::map<uint32_t, std::vector<LoggedRtpPacketIncoming>>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventRtpPacketIncoming(const RtcEventRtpPacketIncoming& other);
|
||||
|
||||
const RtpPacket packet_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_rtp_packet_outgoing.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing(
|
||||
const RtpPacketToSend& packet,
|
||||
int probe_cluster_id)
|
||||
: packet_(packet), probe_cluster_id_(probe_cluster_id) {}
|
||||
|
||||
RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing(
|
||||
const RtcEventRtpPacketOutgoing& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
packet_(other.packet_),
|
||||
probe_cluster_id_(other.probe_cluster_id_) {}
|
||||
|
||||
RtcEventRtpPacketOutgoing::~RtcEventRtpPacketOutgoing() = default;
|
||||
|
||||
std::unique_ptr<RtcEventRtpPacketOutgoing> RtcEventRtpPacketOutgoing::Copy()
|
||||
const {
|
||||
return absl::WrapUnique<RtcEventRtpPacketOutgoing>(
|
||||
new RtcEventRtpPacketOutgoing(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_RTP_PACKET_OUTGOING_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtpPacketToSend;
|
||||
|
||||
class RtcEventRtpPacketOutgoing final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::RtpPacketOutgoing;
|
||||
|
||||
RtcEventRtpPacketOutgoing(const RtpPacketToSend& packet,
|
||||
int probe_cluster_id);
|
||||
~RtcEventRtpPacketOutgoing() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return false; }
|
||||
|
||||
std::unique_ptr<RtcEventRtpPacketOutgoing> Copy() const;
|
||||
|
||||
size_t packet_length() const { return packet_.size(); }
|
||||
|
||||
rtc::ArrayView<const uint8_t> RawHeader() const {
|
||||
return rtc::MakeArrayView(packet_.data(), header_length());
|
||||
}
|
||||
uint32_t Ssrc() const { return packet_.Ssrc(); }
|
||||
uint32_t Timestamp() const { return packet_.Timestamp(); }
|
||||
uint16_t SequenceNumber() const { return packet_.SequenceNumber(); }
|
||||
uint8_t PayloadType() const { return packet_.PayloadType(); }
|
||||
bool Marker() const { return packet_.Marker(); }
|
||||
template <typename ExtensionTrait, typename... Args>
|
||||
bool GetExtension(Args&&... args) const {
|
||||
return packet_.GetExtension<ExtensionTrait>(std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename ExtensionTrait>
|
||||
rtc::ArrayView<const uint8_t> GetRawExtension() const {
|
||||
return packet_.GetRawExtension<ExtensionTrait>();
|
||||
}
|
||||
template <typename ExtensionTrait>
|
||||
bool HasExtension() const {
|
||||
return packet_.HasExtension<ExtensionTrait>();
|
||||
}
|
||||
|
||||
size_t payload_length() const { return packet_.payload_size(); }
|
||||
size_t header_length() const { return packet_.headers_size(); }
|
||||
size_t padding_length() const { return packet_.padding_size(); }
|
||||
int probe_cluster_id() const { return probe_cluster_id_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::map<uint32_t, std::vector<LoggedRtpPacketOutgoing>>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventRtpPacketOutgoing(const RtcEventRtpPacketOutgoing& other);
|
||||
|
||||
const RtpPacket packet_;
|
||||
// TODO(eladalon): Delete `probe_cluster_id_` along with legacy encoding.
|
||||
const int probe_cluster_id_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_video_receive_stream_config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventVideoReceiveStreamConfig::RtcEventVideoReceiveStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config)
|
||||
: config_(std::move(config)) {
|
||||
RTC_DCHECK(config_);
|
||||
}
|
||||
|
||||
RtcEventVideoReceiveStreamConfig::RtcEventVideoReceiveStreamConfig(
|
||||
const RtcEventVideoReceiveStreamConfig& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
|
||||
|
||||
RtcEventVideoReceiveStreamConfig::~RtcEventVideoReceiveStreamConfig() = default;
|
||||
|
||||
std::unique_ptr<RtcEventVideoReceiveStreamConfig>
|
||||
RtcEventVideoReceiveStreamConfig::Copy() const {
|
||||
return absl::WrapUnique<RtcEventVideoReceiveStreamConfig>(
|
||||
new RtcEventVideoReceiveStreamConfig(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_VIDEO_RECEIVE_STREAM_CONFIG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_RECEIVE_STREAM_CONFIG_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedVideoRecvConfig {
|
||||
LoggedVideoRecvConfig() = default;
|
||||
LoggedVideoRecvConfig(Timestamp timestamp, const rtclog::StreamConfig config)
|
||||
: timestamp(timestamp), config(config) {}
|
||||
|
||||
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();
|
||||
rtclog::StreamConfig config;
|
||||
};
|
||||
|
||||
class RtcEventVideoReceiveStreamConfig final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::VideoReceiveStreamConfig;
|
||||
|
||||
explicit RtcEventVideoReceiveStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config);
|
||||
~RtcEventVideoReceiveStreamConfig() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return true; }
|
||||
|
||||
std::unique_ptr<RtcEventVideoReceiveStreamConfig> Copy() const;
|
||||
|
||||
const rtclog::StreamConfig& config() const { return *config_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedVideoRecvConfig>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventVideoReceiveStreamConfig(
|
||||
const RtcEventVideoReceiveStreamConfig& other);
|
||||
|
||||
const std::unique_ptr<const rtclog::StreamConfig> config_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_RECEIVE_STREAM_CONFIG_H_
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_video_send_stream_config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RtcEventVideoSendStreamConfig::RtcEventVideoSendStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config)
|
||||
: config_(std::move(config)) {}
|
||||
|
||||
RtcEventVideoSendStreamConfig::RtcEventVideoSendStreamConfig(
|
||||
const RtcEventVideoSendStreamConfig& other)
|
||||
: RtcEvent(other.timestamp_us_),
|
||||
config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
|
||||
|
||||
RtcEventVideoSendStreamConfig::~RtcEventVideoSendStreamConfig() = default;
|
||||
|
||||
std::unique_ptr<RtcEventVideoSendStreamConfig>
|
||||
RtcEventVideoSendStreamConfig::Copy() const {
|
||||
return absl::WrapUnique<RtcEventVideoSendStreamConfig>(
|
||||
new RtcEventVideoSendStreamConfig(*this));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_VIDEO_SEND_STREAM_CONFIG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_SEND_STREAM_CONFIG_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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_field_encoding_parser.h"
|
||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LoggedVideoSendConfig {
|
||||
LoggedVideoSendConfig() = default;
|
||||
LoggedVideoSendConfig(Timestamp timestamp, const rtclog::StreamConfig config)
|
||||
: timestamp(timestamp), config(config) {}
|
||||
|
||||
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();
|
||||
rtclog::StreamConfig config;
|
||||
};
|
||||
|
||||
class RtcEventVideoSendStreamConfig final : public RtcEvent {
|
||||
public:
|
||||
static constexpr Type kType = Type::VideoSendStreamConfig;
|
||||
|
||||
explicit RtcEventVideoSendStreamConfig(
|
||||
std::unique_ptr<rtclog::StreamConfig> config);
|
||||
~RtcEventVideoSendStreamConfig() override;
|
||||
|
||||
Type GetType() const override { return kType; }
|
||||
bool IsConfigEvent() const override { return true; }
|
||||
|
||||
std::unique_ptr<RtcEventVideoSendStreamConfig> Copy() const;
|
||||
|
||||
const rtclog::StreamConfig& config() const { return *config_; }
|
||||
|
||||
static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
|
||||
// TODO(terelius): Implement
|
||||
return "";
|
||||
}
|
||||
|
||||
static RtcEventLogParseStatus Parse(
|
||||
absl::string_view encoded_bytes,
|
||||
bool batched,
|
||||
std::vector<LoggedVideoSendConfig>& output) {
|
||||
// TODO(terelius): Implement
|
||||
return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
private:
|
||||
RtcEventVideoSendStreamConfig(const RtcEventVideoSendStreamConfig& other);
|
||||
|
||||
const std::unique_ptr<const rtclog::StreamConfig> config_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_SEND_STREAM_CONFIG_H_
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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/fake_rtc_event_log.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
bool FakeRtcEventLog::StartLogging(std::unique_ptr<RtcEventLogOutput> output,
|
||||
int64_t output_period_ms) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeRtcEventLog::StopLogging() {}
|
||||
|
||||
void FakeRtcEventLog::Log(std::unique_ptr<RtcEvent> event) {
|
||||
MutexLock lock(&mu_);
|
||||
++count_[event->GetType()];
|
||||
}
|
||||
|
||||
int FakeRtcEventLog::GetEventCount(RtcEvent::Type event_type) {
|
||||
MutexLock lock(&mu_);
|
||||
return count_[event_type];
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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_FAKE_RTC_EVENT_LOG_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakeRtcEventLog : public RtcEventLog {
|
||||
public:
|
||||
FakeRtcEventLog() = default;
|
||||
~FakeRtcEventLog() override = default;
|
||||
|
||||
bool StartLogging(std::unique_ptr<RtcEventLogOutput> output,
|
||||
int64_t output_period_ms) override;
|
||||
void StopLogging() override;
|
||||
void Log(std::unique_ptr<RtcEvent> event) override;
|
||||
int GetEventCount(RtcEvent::Type event_type);
|
||||
|
||||
private:
|
||||
Mutex mu_;
|
||||
std::map<RtcEvent::Type, int> count_ RTC_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_H_
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2018 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/fake_rtc_event_log_factory.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
#include "logging/rtc_event_log/fake_rtc_event_log.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
absl::Nonnull<std::unique_ptr<RtcEventLog>> FakeRtcEventLogFactory::Create(
|
||||
const Environment& /*env*/) const {
|
||||
auto fake_event_log = std::make_unique<FakeRtcEventLog>();
|
||||
const_cast<FakeRtcEventLog*&>(last_log_created_) = fake_event_log.get();
|
||||
return fake_event_log;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 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_FAKE_RTC_EVENT_LOG_FACTORY_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
|
||||
#include "logging/rtc_event_log/fake_rtc_event_log.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakeRtcEventLogFactory : public RtcEventLogFactoryInterface {
|
||||
public:
|
||||
FakeRtcEventLogFactory() = default;
|
||||
~FakeRtcEventLogFactory() override = default;
|
||||
|
||||
absl::Nonnull<std::unique_ptr<RtcEventLog>> Create(
|
||||
const Environment& env) const override;
|
||||
|
||||
FakeRtcEventLog* last_log_created() { return last_log_created_; }
|
||||
|
||||
private:
|
||||
FakeRtcEventLog* last_log_created_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_FACTORY_H_
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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/ice_logger.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
IceEventLog::IceEventLog() {}
|
||||
IceEventLog::~IceEventLog() {}
|
||||
|
||||
void IceEventLog::LogCandidatePairConfig(
|
||||
IceCandidatePairConfigType type,
|
||||
uint32_t candidate_pair_id,
|
||||
const IceCandidatePairDescription& candidate_pair_desc) {
|
||||
if (event_log_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
candidate_pair_desc_by_id_.emplace(candidate_pair_id, candidate_pair_desc);
|
||||
event_log_->Log(std::make_unique<RtcEventIceCandidatePairConfig>(
|
||||
type, candidate_pair_id, candidate_pair_desc));
|
||||
}
|
||||
|
||||
void IceEventLog::LogCandidatePairEvent(IceCandidatePairEventType type,
|
||||
uint32_t candidate_pair_id,
|
||||
uint32_t transaction_id) {
|
||||
if (event_log_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
event_log_->Log(std::make_unique<RtcEventIceCandidatePair>(
|
||||
type, candidate_pair_id, transaction_id));
|
||||
}
|
||||
|
||||
void IceEventLog::DumpCandidatePairDescriptionToMemoryAsConfigEvents() const {
|
||||
for (const auto& desc_id_pair : candidate_pair_desc_by_id_) {
|
||||
event_log_->Log(std::make_unique<RtcEventIceCandidatePairConfig>(
|
||||
IceCandidatePairConfigType::kUpdated, desc_id_pair.first,
|
||||
desc_id_pair.second));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_ICE_LOGGER_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_ICE_LOGGER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#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"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtcEventLog;
|
||||
|
||||
// IceEventLog wraps RtcEventLog and provides structural logging of ICE-specific
|
||||
// events. The logged events are serialized with other RtcEvent's if protobuf is
|
||||
// enabled in the build.
|
||||
class IceEventLog {
|
||||
public:
|
||||
IceEventLog();
|
||||
~IceEventLog();
|
||||
|
||||
void set_event_log(RtcEventLog* event_log) { event_log_ = event_log; }
|
||||
|
||||
void LogCandidatePairConfig(
|
||||
IceCandidatePairConfigType type,
|
||||
uint32_t candidate_pair_id,
|
||||
const IceCandidatePairDescription& candidate_pair_desc);
|
||||
|
||||
void LogCandidatePairEvent(IceCandidatePairEventType type,
|
||||
uint32_t candidate_pair_id,
|
||||
uint32_t transaction_id);
|
||||
|
||||
// This method constructs a config event for each candidate pair with their
|
||||
// description and logs these config events. It is intended to be called when
|
||||
// logging starts to ensure that we have at least one config for each
|
||||
// candidate pair id.
|
||||
void DumpCandidatePairDescriptionToMemoryAsConfigEvents() const;
|
||||
|
||||
private:
|
||||
RtcEventLog* event_log_ = nullptr;
|
||||
std::unordered_map<uint32_t, IceCandidatePairDescription>
|
||||
candidate_pair_desc_by_id_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_ICE_LOGGER_H_
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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_OUTPUT_RTC_EVENT_LOG_OUTPUT_FILE_H_
|
||||
#define LOGGING_RTC_EVENT_LOG_OUTPUT_RTC_EVENT_LOG_OUTPUT_FILE_H_
|
||||
|
||||
// TODO(bugs.webrtc.org/6463): For backwards compatibility; delete as soon as
|
||||
// downstream dependencies are updated.
|
||||
|
||||
#include "api/rtc_event_log_output_file.h"
|
||||
|
||||
#endif // LOGGING_RTC_EVENT_LOG_OUTPUT_RTC_EVENT_LOG_OUTPUT_FILE_H_
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
16384
TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc
Normal file
16384
TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc
Normal file
File diff suppressed because it is too large
Load diff
20923
TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h
Normal file
20923
TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue