| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/call/rtc_event_log_parser.h" | 11 #include "webrtc/call/rtc_event_log_parser.h" |
| 12 | 12 |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include <fstream> | 15 #include <fstream> |
| 16 #include <istream> |
| 17 #include <utility> |
| 16 | 18 |
| 17 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 19 #include "webrtc/call.h" | 21 #include "webrtc/call.h" |
| 20 #include "webrtc/call/rtc_event_log.h" | 22 #include "webrtc/call/rtc_event_log.h" |
| 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
| 22 #include "webrtc/system_wrappers/include/file_wrapper.h" | 24 #include "webrtc/system_wrappers/include/file_wrapper.h" |
| 23 | 25 |
| 24 namespace webrtc { | 26 namespace webrtc { |
| 25 | 27 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 return ParsedRtcEventLog::EventType::VIDEO_SENDER_CONFIG_EVENT; | 77 return ParsedRtcEventLog::EventType::VIDEO_SENDER_CONFIG_EVENT; |
| 76 case rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: | 78 case rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: |
| 77 return ParsedRtcEventLog::EventType::AUDIO_RECEIVER_CONFIG_EVENT; | 79 return ParsedRtcEventLog::EventType::AUDIO_RECEIVER_CONFIG_EVENT; |
| 78 case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: | 80 case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: |
| 79 return ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT; | 81 return ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT; |
| 80 } | 82 } |
| 81 RTC_NOTREACHED(); | 83 RTC_NOTREACHED(); |
| 82 return ParsedRtcEventLog::EventType::UNKNOWN_EVENT; | 84 return ParsedRtcEventLog::EventType::UNKNOWN_EVENT; |
| 83 } | 85 } |
| 84 | 86 |
| 85 bool ParseVarInt(std::FILE* file, uint64_t* varint, size_t* bytes_read) { | 87 std::pair<uint64_t, bool> ParseVarInt(std::istream& stream) { |
| 86 uint8_t byte; | 88 uint64_t varint = 0; |
| 87 *varint = 0; | 89 for (size_t bytes_read = 0; bytes_read < 10; ++bytes_read) { |
| 88 for (*bytes_read = 0; *bytes_read < 10 && fread(&byte, 1, 1, file) == 1; | |
| 89 ++(*bytes_read)) { | |
| 90 // The most significant bit of each byte is 0 if it is the last byte in | 90 // The most significant bit of each byte is 0 if it is the last byte in |
| 91 // the varint and 1 otherwise. Thus, we take the 7 least significant bits | 91 // the varint and 1 otherwise. Thus, we take the 7 least significant bits |
| 92 // of each byte and shift them 7 bits for each byte read previously to get | 92 // of each byte and shift them 7 bits for each byte read previously to get |
| 93 // the (unsigned) integer. | 93 // the (unsigned) integer. |
| 94 *varint |= static_cast<uint64_t>(byte & 0x7F) << (7 * *bytes_read); | 94 int byte = stream.get(); |
| 95 if (stream.eof()) { |
| 96 return std::make_pair(varint, false); |
| 97 } |
| 98 RTC_DCHECK(0 <= byte && byte <= 255); |
| 99 varint |= static_cast<uint64_t>(byte & 0x7F) << (7 * bytes_read); |
| 95 if ((byte & 0x80) == 0) { | 100 if ((byte & 0x80) == 0) { |
| 96 return true; | 101 return std::make_pair(varint, true); |
| 97 } | 102 } |
| 98 } | 103 } |
| 99 return false; | 104 return std::make_pair(varint, false); |
| 100 } | 105 } |
| 101 | 106 |
| 102 } // namespace | 107 } // namespace |
| 103 | 108 |
| 104 bool ParsedRtcEventLog::ParseFile(const std::string& filename) { | 109 bool ParsedRtcEventLog::ParseFile(const std::string& filename) { |
| 105 stream_.clear(); | 110 std::ifstream file(filename, std::ios_base::in | std::ios_base::binary); |
| 106 const size_t kMaxEventSize = (1u << 16) - 1; | 111 if (!file.good() || !file.is_open()) { |
| 107 char tmp_buffer[kMaxEventSize]; | |
| 108 | |
| 109 std::FILE* file = fopen(filename.c_str(), "rb"); | |
| 110 if (!file) { | |
| 111 LOG(LS_WARNING) << "Could not open file for reading."; | 112 LOG(LS_WARNING) << "Could not open file for reading."; |
| 112 return false; | 113 return false; |
| 113 } | 114 } |
| 114 | 115 |
| 116 return ParseStream(file); |
| 117 } |
| 118 |
| 119 bool ParsedRtcEventLog::ParseString(const std::string& s) { |
| 120 std::istringstream stream(s, std::ios_base::in | std::ios_base::binary); |
| 121 return ParseStream(stream); |
| 122 } |
| 123 |
| 124 bool ParsedRtcEventLog::ParseStream(std::istream& stream) { |
| 125 events_.clear(); |
| 126 const size_t kMaxEventSize = (1u << 16) - 1; |
| 127 char tmp_buffer[kMaxEventSize]; |
| 128 uint64_t tag; |
| 129 uint64_t message_length; |
| 130 bool success; |
| 131 |
| 132 RTC_DCHECK(stream.good()); |
| 133 |
| 115 while (1) { | 134 while (1) { |
| 116 // Peek at the next message tag. The tag number is defined as | 135 // Check whether we have reached end of file. |
| 136 stream.peek(); |
| 137 if (stream.eof()) { |
| 138 return true; |
| 139 } |
| 140 |
| 141 // Read the next message tag. The tag number is defined as |
| 117 // (fieldnumber << 3) | wire_type. In our case, the field number is | 142 // (fieldnumber << 3) | wire_type. In our case, the field number is |
| 118 // supposed to be 1 and the wire type for an length-delimited field is 2. | 143 // supposed to be 1 and the wire type for an length-delimited field is 2. |
| 119 const uint64_t kExpectedTag = (1 << 3) | 2; | 144 const uint64_t kExpectedTag = (1 << 3) | 2; |
| 120 uint64_t tag; | 145 std::tie(tag, success) = ParseVarInt(stream); |
| 121 size_t bytes_read; | 146 if (!success) { |
| 122 if (!ParseVarInt(file, &tag, &bytes_read) || tag != kExpectedTag) { | |
| 123 fclose(file); | |
| 124 if (bytes_read == 0) { | |
| 125 return true; // Reached end of file. | |
| 126 } | |
| 127 LOG(LS_WARNING) << "Missing field tag from beginning of protobuf event."; | 147 LOG(LS_WARNING) << "Missing field tag from beginning of protobuf event."; |
| 128 return false; | 148 return false; |
| 149 } else if (tag != kExpectedTag) { |
| 150 LOG(LS_WARNING) << "Unexpected field tag at beginning of protobuf event."; |
| 151 return false; |
| 129 } | 152 } |
| 130 | 153 |
| 131 // Peek at the length field. | 154 // Read the length field. |
| 132 uint64_t message_length; | 155 std::tie(message_length, success) = ParseVarInt(stream); |
| 133 if (!ParseVarInt(file, &message_length, &bytes_read)) { | 156 if (!success) { |
| 134 LOG(LS_WARNING) << "Missing message length after protobuf field tag."; | 157 LOG(LS_WARNING) << "Missing message length after protobuf field tag."; |
| 135 fclose(file); | |
| 136 return false; | 158 return false; |
| 137 } else if (message_length > kMaxEventSize) { | 159 } else if (message_length > kMaxEventSize) { |
| 138 LOG(LS_WARNING) << "Protobuf message length is too large."; | 160 LOG(LS_WARNING) << "Protobuf message length is too large."; |
| 139 fclose(file); | |
| 140 return false; | 161 return false; |
| 141 } | 162 } |
| 142 | 163 |
| 143 if (fread(tmp_buffer, 1, message_length, file) != message_length) { | 164 // Read the next protobuf event to a temporary char buffer. |
| 165 stream.read(tmp_buffer, message_length); |
| 166 if (stream.gcount() != static_cast<int>(message_length)) { |
| 144 LOG(LS_WARNING) << "Failed to read protobuf message from file."; | 167 LOG(LS_WARNING) << "Failed to read protobuf message from file."; |
| 145 fclose(file); | |
| 146 return false; | 168 return false; |
| 147 } | 169 } |
| 148 | 170 |
| 171 // Parse the protobuf event from the buffer. |
| 149 rtclog::Event event; | 172 rtclog::Event event; |
| 150 if (!event.ParseFromArray(tmp_buffer, message_length)) { | 173 if (!event.ParseFromArray(tmp_buffer, message_length)) { |
| 151 LOG(LS_WARNING) << "Failed to parse protobuf message."; | 174 LOG(LS_WARNING) << "Failed to parse protobuf message."; |
| 152 fclose(file); | |
| 153 return false; | 175 return false; |
| 154 } | 176 } |
| 155 stream_.push_back(event); | 177 events_.push_back(event); |
| 156 } | 178 } |
| 157 } | 179 } |
| 158 | 180 |
| 159 size_t ParsedRtcEventLog::GetNumberOfEvents() const { | 181 size_t ParsedRtcEventLog::GetNumberOfEvents() const { |
| 160 return stream_.size(); | 182 return events_.size(); |
| 161 } | 183 } |
| 162 | 184 |
| 163 int64_t ParsedRtcEventLog::GetTimestamp(size_t index) const { | 185 int64_t ParsedRtcEventLog::GetTimestamp(size_t index) const { |
| 164 RTC_CHECK_LT(index, GetNumberOfEvents()); | 186 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 165 const rtclog::Event& event = stream_[index]; | 187 const rtclog::Event& event = events_[index]; |
| 166 RTC_CHECK(event.has_timestamp_us()); | 188 RTC_CHECK(event.has_timestamp_us()); |
| 167 return event.timestamp_us(); | 189 return event.timestamp_us(); |
| 168 } | 190 } |
| 169 | 191 |
| 170 ParsedRtcEventLog::EventType ParsedRtcEventLog::GetEventType( | 192 ParsedRtcEventLog::EventType ParsedRtcEventLog::GetEventType( |
| 171 size_t index) const { | 193 size_t index) const { |
| 172 RTC_CHECK_LT(index, GetNumberOfEvents()); | 194 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 173 const rtclog::Event& event = stream_[index]; | 195 const rtclog::Event& event = events_[index]; |
| 174 RTC_CHECK(event.has_type()); | 196 RTC_CHECK(event.has_type()); |
| 175 return GetRuntimeEventType(event.type()); | 197 return GetRuntimeEventType(event.type()); |
| 176 } | 198 } |
| 177 | 199 |
| 178 // The header must have space for at least IP_PACKET_SIZE bytes. | 200 // The header must have space for at least IP_PACKET_SIZE bytes. |
| 179 void ParsedRtcEventLog::GetRtpHeader(size_t index, | 201 void ParsedRtcEventLog::GetRtpHeader(size_t index, |
| 180 PacketDirection* incoming, | 202 PacketDirection* incoming, |
| 181 MediaType* media_type, | 203 MediaType* media_type, |
| 182 uint8_t* header, | 204 uint8_t* header, |
| 183 size_t* header_length, | 205 size_t* header_length, |
| 184 size_t* total_length) const { | 206 size_t* total_length) const { |
| 185 RTC_CHECK_LT(index, GetNumberOfEvents()); | 207 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 186 const rtclog::Event& event = stream_[index]; | 208 const rtclog::Event& event = events_[index]; |
| 187 RTC_CHECK(event.has_type()); | 209 RTC_CHECK(event.has_type()); |
| 188 RTC_CHECK_EQ(event.type(), rtclog::Event::RTP_EVENT); | 210 RTC_CHECK_EQ(event.type(), rtclog::Event::RTP_EVENT); |
| 189 RTC_CHECK(event.has_rtp_packet()); | 211 RTC_CHECK(event.has_rtp_packet()); |
| 190 const rtclog::RtpPacket& rtp_packet = event.rtp_packet(); | 212 const rtclog::RtpPacket& rtp_packet = event.rtp_packet(); |
| 191 // Get direction of packet. | 213 // Get direction of packet. |
| 192 RTC_CHECK(rtp_packet.has_incoming()); | 214 RTC_CHECK(rtp_packet.has_incoming()); |
| 193 if (incoming != nullptr) { | 215 if (incoming != nullptr) { |
| 194 *incoming = rtp_packet.incoming() ? kIncomingPacket : kOutgoingPacket; | 216 *incoming = rtp_packet.incoming() ? kIncomingPacket : kOutgoingPacket; |
| 195 } | 217 } |
| 196 // Get media type. | 218 // Get media type. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 218 } | 240 } |
| 219 } | 241 } |
| 220 | 242 |
| 221 // The packet must have space for at least IP_PACKET_SIZE bytes. | 243 // The packet must have space for at least IP_PACKET_SIZE bytes. |
| 222 void ParsedRtcEventLog::GetRtcpPacket(size_t index, | 244 void ParsedRtcEventLog::GetRtcpPacket(size_t index, |
| 223 PacketDirection* incoming, | 245 PacketDirection* incoming, |
| 224 MediaType* media_type, | 246 MediaType* media_type, |
| 225 uint8_t* packet, | 247 uint8_t* packet, |
| 226 size_t* length) const { | 248 size_t* length) const { |
| 227 RTC_CHECK_LT(index, GetNumberOfEvents()); | 249 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 228 const rtclog::Event& event = stream_[index]; | 250 const rtclog::Event& event = events_[index]; |
| 229 RTC_CHECK(event.has_type()); | 251 RTC_CHECK(event.has_type()); |
| 230 RTC_CHECK_EQ(event.type(), rtclog::Event::RTCP_EVENT); | 252 RTC_CHECK_EQ(event.type(), rtclog::Event::RTCP_EVENT); |
| 231 RTC_CHECK(event.has_rtcp_packet()); | 253 RTC_CHECK(event.has_rtcp_packet()); |
| 232 const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet(); | 254 const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet(); |
| 233 // Get direction of packet. | 255 // Get direction of packet. |
| 234 RTC_CHECK(rtcp_packet.has_incoming()); | 256 RTC_CHECK(rtcp_packet.has_incoming()); |
| 235 if (incoming != nullptr) { | 257 if (incoming != nullptr) { |
| 236 *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket; | 258 *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket; |
| 237 } | 259 } |
| 238 // Get media type. | 260 // Get media type. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 251 static_cast<unsigned>(IP_PACKET_SIZE)); | 273 static_cast<unsigned>(IP_PACKET_SIZE)); |
| 252 memcpy(packet, rtcp_packet.packet_data().data(), | 274 memcpy(packet, rtcp_packet.packet_data().data(), |
| 253 rtcp_packet.packet_data().size()); | 275 rtcp_packet.packet_data().size()); |
| 254 } | 276 } |
| 255 } | 277 } |
| 256 | 278 |
| 257 void ParsedRtcEventLog::GetVideoReceiveConfig( | 279 void ParsedRtcEventLog::GetVideoReceiveConfig( |
| 258 size_t index, | 280 size_t index, |
| 259 VideoReceiveStream::Config* config) const { | 281 VideoReceiveStream::Config* config) const { |
| 260 RTC_CHECK_LT(index, GetNumberOfEvents()); | 282 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 261 const rtclog::Event& event = stream_[index]; | 283 const rtclog::Event& event = events_[index]; |
| 262 RTC_CHECK(config != nullptr); | 284 RTC_CHECK(config != nullptr); |
| 263 RTC_CHECK(event.has_type()); | 285 RTC_CHECK(event.has_type()); |
| 264 RTC_CHECK_EQ(event.type(), rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); | 286 RTC_CHECK_EQ(event.type(), rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); |
| 265 RTC_CHECK(event.has_video_receiver_config()); | 287 RTC_CHECK(event.has_video_receiver_config()); |
| 266 const rtclog::VideoReceiveConfig& receiver_config = | 288 const rtclog::VideoReceiveConfig& receiver_config = |
| 267 event.video_receiver_config(); | 289 event.video_receiver_config(); |
| 268 // Get SSRCs. | 290 // Get SSRCs. |
| 269 RTC_CHECK(receiver_config.has_remote_ssrc()); | 291 RTC_CHECK(receiver_config.has_remote_ssrc()); |
| 270 config->rtp.remote_ssrc = receiver_config.remote_ssrc(); | 292 config->rtp.remote_ssrc = receiver_config.remote_ssrc(); |
| 271 RTC_CHECK(receiver_config.has_local_ssrc()); | 293 RTC_CHECK(receiver_config.has_local_ssrc()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 decoder.payload_name = receiver_config.decoders(i).name(); | 328 decoder.payload_name = receiver_config.decoders(i).name(); |
| 307 decoder.payload_type = receiver_config.decoders(i).payload_type(); | 329 decoder.payload_type = receiver_config.decoders(i).payload_type(); |
| 308 config->decoders.push_back(decoder); | 330 config->decoders.push_back(decoder); |
| 309 } | 331 } |
| 310 } | 332 } |
| 311 | 333 |
| 312 void ParsedRtcEventLog::GetVideoSendConfig( | 334 void ParsedRtcEventLog::GetVideoSendConfig( |
| 313 size_t index, | 335 size_t index, |
| 314 VideoSendStream::Config* config) const { | 336 VideoSendStream::Config* config) const { |
| 315 RTC_CHECK_LT(index, GetNumberOfEvents()); | 337 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 316 const rtclog::Event& event = stream_[index]; | 338 const rtclog::Event& event = events_[index]; |
| 317 RTC_CHECK(config != nullptr); | 339 RTC_CHECK(config != nullptr); |
| 318 RTC_CHECK(event.has_type()); | 340 RTC_CHECK(event.has_type()); |
| 319 RTC_CHECK_EQ(event.type(), rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); | 341 RTC_CHECK_EQ(event.type(), rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); |
| 320 RTC_CHECK(event.has_video_sender_config()); | 342 RTC_CHECK(event.has_video_sender_config()); |
| 321 const rtclog::VideoSendConfig& sender_config = event.video_sender_config(); | 343 const rtclog::VideoSendConfig& sender_config = event.video_sender_config(); |
| 322 // Get SSRCs. | 344 // Get SSRCs. |
| 323 config->rtp.ssrcs.clear(); | 345 config->rtp.ssrcs.clear(); |
| 324 for (int i = 0; i < sender_config.ssrcs_size(); i++) { | 346 for (int i = 0; i < sender_config.ssrcs_size(); i++) { |
| 325 config->rtp.ssrcs.push_back(sender_config.ssrcs(i)); | 347 config->rtp.ssrcs.push_back(sender_config.ssrcs(i)); |
| 326 } | 348 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 349 RTC_CHECK(sender_config.has_encoder()); | 371 RTC_CHECK(sender_config.has_encoder()); |
| 350 RTC_CHECK(sender_config.encoder().has_name()); | 372 RTC_CHECK(sender_config.encoder().has_name()); |
| 351 RTC_CHECK(sender_config.encoder().has_payload_type()); | 373 RTC_CHECK(sender_config.encoder().has_payload_type()); |
| 352 config->encoder_settings.payload_name = sender_config.encoder().name(); | 374 config->encoder_settings.payload_name = sender_config.encoder().name(); |
| 353 config->encoder_settings.payload_type = | 375 config->encoder_settings.payload_type = |
| 354 sender_config.encoder().payload_type(); | 376 sender_config.encoder().payload_type(); |
| 355 } | 377 } |
| 356 | 378 |
| 357 void ParsedRtcEventLog::GetAudioPlayout(size_t index, uint32_t* ssrc) const { | 379 void ParsedRtcEventLog::GetAudioPlayout(size_t index, uint32_t* ssrc) const { |
| 358 RTC_CHECK_LT(index, GetNumberOfEvents()); | 380 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 359 const rtclog::Event& event = stream_[index]; | 381 const rtclog::Event& event = events_[index]; |
| 360 RTC_CHECK(event.has_type()); | 382 RTC_CHECK(event.has_type()); |
| 361 RTC_CHECK_EQ(event.type(), rtclog::Event::AUDIO_PLAYOUT_EVENT); | 383 RTC_CHECK_EQ(event.type(), rtclog::Event::AUDIO_PLAYOUT_EVENT); |
| 362 RTC_CHECK(event.has_audio_playout_event()); | 384 RTC_CHECK(event.has_audio_playout_event()); |
| 363 const rtclog::AudioPlayoutEvent& loss_event = event.audio_playout_event(); | 385 const rtclog::AudioPlayoutEvent& loss_event = event.audio_playout_event(); |
| 364 RTC_CHECK(loss_event.has_local_ssrc()); | 386 RTC_CHECK(loss_event.has_local_ssrc()); |
| 365 if (ssrc != nullptr) { | 387 if (ssrc != nullptr) { |
| 366 *ssrc = loss_event.local_ssrc(); | 388 *ssrc = loss_event.local_ssrc(); |
| 367 } | 389 } |
| 368 } | 390 } |
| 369 | 391 |
| 370 void ParsedRtcEventLog::GetBwePacketLossEvent(size_t index, | 392 void ParsedRtcEventLog::GetBwePacketLossEvent(size_t index, |
| 371 int32_t* bitrate, | 393 int32_t* bitrate, |
| 372 uint8_t* fraction_loss, | 394 uint8_t* fraction_loss, |
| 373 int32_t* total_packets) const { | 395 int32_t* total_packets) const { |
| 374 RTC_CHECK_LT(index, GetNumberOfEvents()); | 396 RTC_CHECK_LT(index, GetNumberOfEvents()); |
| 375 const rtclog::Event& event = stream_[index]; | 397 const rtclog::Event& event = events_[index]; |
| 376 RTC_CHECK(event.has_type()); | 398 RTC_CHECK(event.has_type()); |
| 377 RTC_CHECK_EQ(event.type(), rtclog::Event::BWE_PACKET_LOSS_EVENT); | 399 RTC_CHECK_EQ(event.type(), rtclog::Event::BWE_PACKET_LOSS_EVENT); |
| 378 RTC_CHECK(event.has_bwe_packet_loss_event()); | 400 RTC_CHECK(event.has_bwe_packet_loss_event()); |
| 379 const rtclog::BwePacketLossEvent& loss_event = event.bwe_packet_loss_event(); | 401 const rtclog::BwePacketLossEvent& loss_event = event.bwe_packet_loss_event(); |
| 380 RTC_CHECK(loss_event.has_bitrate()); | 402 RTC_CHECK(loss_event.has_bitrate()); |
| 381 if (bitrate != nullptr) { | 403 if (bitrate != nullptr) { |
| 382 *bitrate = loss_event.bitrate(); | 404 *bitrate = loss_event.bitrate(); |
| 383 } | 405 } |
| 384 RTC_CHECK(loss_event.has_fraction_loss()); | 406 RTC_CHECK(loss_event.has_fraction_loss()); |
| 385 if (fraction_loss != nullptr) { | 407 if (fraction_loss != nullptr) { |
| 386 *fraction_loss = loss_event.fraction_loss(); | 408 *fraction_loss = loss_event.fraction_loss(); |
| 387 } | 409 } |
| 388 RTC_CHECK(loss_event.has_total_packets()); | 410 RTC_CHECK(loss_event.has_total_packets()); |
| 389 if (total_packets != nullptr) { | 411 if (total_packets != nullptr) { |
| 390 *total_packets = loss_event.total_packets(); | 412 *total_packets = loss_event.total_packets(); |
| 391 } | 413 } |
| 392 } | 414 } |
| 393 | 415 |
| 394 } // namespace webrtc | 416 } // namespace webrtc |
| OLD | NEW |