| /* | |
| * 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 <cstdint> | |
| #include <deque> | |
| #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_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_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" | |
| 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::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[{.type = (*it)->GetType(), | |
| .secondary_group_key = (*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 |