blob: c929bc7e572f0335395e85a1c34b69875f63fc40 [file] [log] [blame]
Bjorn Terelius36411852015-07-30 12:45:18 +02001/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Peter Boström5c389d32015-09-25 13:58:30 +020011#include "webrtc/call/rtc_event_log.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020012
terelius4311ba52016-04-22 12:40:37 -070013#include <limits>
terelius1adce142015-10-16 08:51:08 -070014#include <vector>
Bjorn Terelius36411852015-07-30 12:45:18 +020015
16#include "webrtc/base/checks.h"
terelius4311ba52016-04-22 12:40:37 -070017#include "webrtc/base/constructormagic.h"
18#include "webrtc/base/event.h"
19#include "webrtc/base/swap_queue.h"
20#include "webrtc/base/thread_checker.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020021#include "webrtc/call.h"
terelius4311ba52016-04-22 12:40:37 -070022#include "webrtc/call/rtc_event_log_helper_thread.h"
tereliusd66daa22015-11-06 09:00:18 -080023#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
terelius2f9fd5d2015-09-04 03:39:42 -070024#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
tereliusd66daa22015-11-06 09:00:18 -080025#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010026#include "webrtc/system_wrappers/include/clock.h"
27#include "webrtc/system_wrappers/include/file_wrapper.h"
terelius4311ba52016-04-22 12:40:37 -070028#include "webrtc/system_wrappers/include/logging.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020029
30#ifdef ENABLE_RTC_EVENT_LOG
31// Files generated at build-time by the protobuf compiler.
32#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
Peter Boström5c389d32015-09-25 13:58:30 +020033#include "external/webrtc/webrtc/call/rtc_event_log.pb.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020034#else
Peter Boström5c389d32015-09-25 13:58:30 +020035#include "webrtc/call/rtc_event_log.pb.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020036#endif
37#endif
38
39namespace webrtc {
40
41#ifndef ENABLE_RTC_EVENT_LOG
42
43// No-op implementation if flag is not set.
terelius4311ba52016-04-22 12:40:37 -070044class RtcEventLogNullImpl final : public RtcEventLog {
Bjorn Terelius36411852015-07-30 12:45:18 +020045 public:
terelius4311ba52016-04-22 12:40:37 -070046 bool StartLogging(const std::string& file_name,
47 int64_t max_size_bytes) override {
48 return false;
49 }
50 bool StartLogging(rtc::PlatformFile platform_file,
51 int64_t max_size_bytes) override {
52 return false;
53 }
54 void StopLogging() override {}
Bjorn Terelius36411852015-07-30 12:45:18 +020055 void LogVideoReceiveStreamConfig(
56 const VideoReceiveStream::Config& config) override {}
57 void LogVideoSendStreamConfig(
58 const VideoSendStream::Config& config) override {}
terelius429c3452016-01-21 05:42:04 -080059 void LogRtpHeader(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +020060 MediaType media_type,
61 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -070062 size_t packet_length) override {}
terelius429c3452016-01-21 05:42:04 -080063 void LogRtcpPacket(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +020064 MediaType media_type,
65 const uint8_t* packet,
66 size_t length) override {}
Ivo Creusenae856f22015-09-17 16:30:16 +020067 void LogAudioPlayout(uint32_t ssrc) override {}
terelius006d93d2015-11-05 12:02:15 -080068 void LogBwePacketLossEvent(int32_t bitrate,
69 uint8_t fraction_loss,
70 int32_t total_packets) override {}
Bjorn Terelius36411852015-07-30 12:45:18 +020071};
72
73#else // ENABLE_RTC_EVENT_LOG is defined
74
75class RtcEventLogImpl final : public RtcEventLog {
76 public:
terelius4311ba52016-04-22 12:40:37 -070077 explicit RtcEventLogImpl(const Clock* clock);
78 ~RtcEventLogImpl() override;
terelius1adce142015-10-16 08:51:08 -070079
terelius4311ba52016-04-22 12:40:37 -070080 bool StartLogging(const std::string& file_name,
81 int64_t max_size_bytes) override;
82 bool StartLogging(rtc::PlatformFile platform_file,
83 int64_t max_size_bytes) override;
Bjorn Terelius36411852015-07-30 12:45:18 +020084 void StopLogging() override;
85 void LogVideoReceiveStreamConfig(
86 const VideoReceiveStream::Config& config) override;
87 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override;
terelius429c3452016-01-21 05:42:04 -080088 void LogRtpHeader(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +020089 MediaType media_type,
90 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -070091 size_t packet_length) override;
terelius429c3452016-01-21 05:42:04 -080092 void LogRtcpPacket(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +020093 MediaType media_type,
94 const uint8_t* packet,
95 size_t length) override;
Ivo Creusenae856f22015-09-17 16:30:16 +020096 void LogAudioPlayout(uint32_t ssrc) override;
terelius006d93d2015-11-05 12:02:15 -080097 void LogBwePacketLossEvent(int32_t bitrate,
98 uint8_t fraction_loss,
99 int32_t total_packets) override;
Bjorn Terelius36411852015-07-30 12:45:18 +0200100
101 private:
terelius4311ba52016-04-22 12:40:37 -0700102 // Message queue for passing control messages to the logging thread.
103 SwapQueue<RtcEventLogHelperThread::ControlMessage> message_queue_;
Bjorn Terelius36411852015-07-30 12:45:18 +0200104
terelius4311ba52016-04-22 12:40:37 -0700105 // Message queue for passing events to the logging thread.
106 SwapQueue<std::unique_ptr<rtclog::Event> > event_queue_;
terelius1adce142015-10-16 08:51:08 -0700107
terelius4311ba52016-04-22 12:40:37 -0700108 rtc::Event wake_up_;
109 rtc::Event stopped_;
110
terelius1adce142015-10-16 08:51:08 -0700111 const Clock* const clock_;
terelius4311ba52016-04-22 12:40:37 -0700112
113 RtcEventLogHelperThread helper_thread_;
114 rtc::ThreadChecker thread_checker_;
115
116 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtcEventLogImpl);
Bjorn Terelius36411852015-07-30 12:45:18 +0200117};
118
119namespace {
120// The functions in this namespace convert enums from the runtime format
121// that the rest of the WebRtc project can use, to the corresponding
122// serialized enum which is defined by the protobuf.
123
pbosda903ea2015-10-02 02:36:56 -0700124rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
Bjorn Terelius36411852015-07-30 12:45:18 +0200125 switch (rtcp_mode) {
pbosda903ea2015-10-02 02:36:56 -0700126 case RtcpMode::kCompound:
Bjorn Terelius36411852015-07-30 12:45:18 +0200127 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
pbosda903ea2015-10-02 02:36:56 -0700128 case RtcpMode::kReducedSize:
Bjorn Terelius36411852015-07-30 12:45:18 +0200129 return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE;
pbosda903ea2015-10-02 02:36:56 -0700130 case RtcpMode::kOff:
131 RTC_NOTREACHED();
132 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
Bjorn Terelius36411852015-07-30 12:45:18 +0200133 }
134 RTC_NOTREACHED();
135 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
136}
137
138rtclog::MediaType ConvertMediaType(MediaType media_type) {
139 switch (media_type) {
140 case MediaType::ANY:
141 return rtclog::MediaType::ANY;
142 case MediaType::AUDIO:
143 return rtclog::MediaType::AUDIO;
144 case MediaType::VIDEO:
145 return rtclog::MediaType::VIDEO;
146 case MediaType::DATA:
147 return rtclog::MediaType::DATA;
148 }
149 RTC_NOTREACHED();
150 return rtclog::ANY;
151}
152
terelius4311ba52016-04-22 12:40:37 -0700153// The RTP and RTCP buffers reserve space for twice the expected number of
154// sent packets because they also contain received packets.
155static const int kEventsPerSecond = 1000;
156static const int kControlMessagesPerSecond = 10;
terelius1adce142015-10-16 08:51:08 -0700157} // namespace
158
Bjorn Terelius36411852015-07-30 12:45:18 +0200159// RtcEventLogImpl member functions.
terelius4311ba52016-04-22 12:40:37 -0700160RtcEventLogImpl::RtcEventLogImpl(const Clock* clock)
161 // Allocate buffers for roughly one second of history.
162 : message_queue_(kControlMessagesPerSecond),
163 event_queue_(kEventsPerSecond),
164 wake_up_(false, false),
165 stopped_(false, false),
166 clock_(clock),
167 helper_thread_(&message_queue_,
168 &event_queue_,
169 &wake_up_,
170 &stopped_,
171 clock),
172 thread_checker_() {
173 thread_checker_.DetachFromThread();
terelius1adce142015-10-16 08:51:08 -0700174}
175
terelius4311ba52016-04-22 12:40:37 -0700176RtcEventLogImpl::~RtcEventLogImpl() {
177 // The RtcEventLogHelperThread destructor closes the file
178 // and waits for the thread to terminate.
terelius1adce142015-10-16 08:51:08 -0700179}
Bjorn Terelius36411852015-07-30 12:45:18 +0200180
terelius4311ba52016-04-22 12:40:37 -0700181bool RtcEventLogImpl::StartLogging(const std::string& file_name,
182 int64_t max_size_bytes) {
183 RTC_DCHECK(thread_checker_.CalledOnValidThread());
184 RtcEventLogHelperThread::ControlMessage message;
185 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE;
186 message.max_size_bytes = max_size_bytes;
187 message.start_time = clock_->TimeInMicroseconds();
188 message.stop_time = std::numeric_limits<int64_t>::max();
189 message.file.reset(FileWrapper::Create());
190 if (message.file->OpenFile(file_name.c_str(), false) != 0) {
ivoc112a3d82015-10-16 02:22:18 -0700191 return false;
192 }
terelius4311ba52016-04-22 12:40:37 -0700193 if (!message_queue_.Insert(&message)) {
194 LOG(LS_WARNING) << "Message queue full. Can't start logging.";
ivoc112a3d82015-10-16 02:22:18 -0700195 return false;
196 }
ivoc112a3d82015-10-16 02:22:18 -0700197 return true;
198}
199
terelius4311ba52016-04-22 12:40:37 -0700200bool RtcEventLogImpl::StartLogging(rtc::PlatformFile platform_file,
201 int64_t max_size_bytes) {
202 RTC_DCHECK(thread_checker_.CalledOnValidThread());
203 RtcEventLogHelperThread::ControlMessage message;
204 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE;
205 message.max_size_bytes = max_size_bytes;
206 message.start_time = clock_->TimeInMicroseconds();
207 message.stop_time = std::numeric_limits<int64_t>::max();
208 message.file.reset(FileWrapper::Create());
209 FILE* file_handle = rtc::FdopenPlatformFileForWriting(platform_file);
210 if (!file_handle) {
211 return false;
terelius1adce142015-10-16 08:51:08 -0700212 }
terelius4311ba52016-04-22 12:40:37 -0700213 if (message.file->OpenFromFileHandle(file_handle, true, false) != 0) {
214 return false;
Bjorn Terelius36411852015-07-30 12:45:18 +0200215 }
terelius4311ba52016-04-22 12:40:37 -0700216 if (!message_queue_.Insert(&message)) {
217 LOG(LS_WARNING) << "Message queue full. Can't start logging.";
218 return false;
219 }
220 return true;
Bjorn Terelius36411852015-07-30 12:45:18 +0200221}
222
223void RtcEventLogImpl::StopLogging() {
terelius4311ba52016-04-22 12:40:37 -0700224 RTC_DCHECK(thread_checker_.CalledOnValidThread());
225 RtcEventLogHelperThread::ControlMessage message;
226 message.message_type = RtcEventLogHelperThread::ControlMessage::STOP_FILE;
227 message.stop_time = clock_->TimeInMicroseconds();
228 while (!message_queue_.Insert(&message)) {
229 // TODO(terelius): We would like to have a blocking Insert function in the
230 // SwapQueue, but for the time being we will just clear any previous
231 // messages.
232 // Since StopLogging waits for the thread, it is essential that we don't
233 // clear any STOP_FILE messages. To ensure that there is only one call at a
234 // time, we require that all calls to StopLogging are made on the same
235 // thread.
236 LOG(LS_WARNING) << "Message queue full. Clearing queue to stop logging.";
237 message_queue_.Clear();
238 }
239 wake_up_.Set(); // Request the output thread to wake up.
240 stopped_.Wait(rtc::Event::kForever); // Wait for the log to stop.
Bjorn Terelius36411852015-07-30 12:45:18 +0200241}
242
243void RtcEventLogImpl::LogVideoReceiveStreamConfig(
244 const VideoReceiveStream::Config& config) {
terelius4311ba52016-04-22 12:40:37 -0700245 std::unique_ptr<rtclog::Event> event(new rtclog::Event());
246 event->set_timestamp_us(clock_->TimeInMicroseconds());
247 event->set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
Bjorn Terelius36411852015-07-30 12:45:18 +0200248
249 rtclog::VideoReceiveConfig* receiver_config =
terelius4311ba52016-04-22 12:40:37 -0700250 event->mutable_video_receiver_config();
Bjorn Terelius36411852015-07-30 12:45:18 +0200251 receiver_config->set_remote_ssrc(config.rtp.remote_ssrc);
252 receiver_config->set_local_ssrc(config.rtp.local_ssrc);
253
254 receiver_config->set_rtcp_mode(ConvertRtcpMode(config.rtp.rtcp_mode));
Bjorn Terelius36411852015-07-30 12:45:18 +0200255 receiver_config->set_remb(config.rtp.remb);
256
257 for (const auto& kv : config.rtp.rtx) {
258 rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
259 rtx->set_payload_type(kv.first);
260 rtx->mutable_config()->set_rtx_ssrc(kv.second.ssrc);
261 rtx->mutable_config()->set_rtx_payload_type(kv.second.payload_type);
262 }
263
264 for (const auto& e : config.rtp.extensions) {
265 rtclog::RtpHeaderExtension* extension =
266 receiver_config->add_header_extensions();
267 extension->set_name(e.name);
268 extension->set_id(e.id);
269 }
270
271 for (const auto& d : config.decoders) {
272 rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
273 decoder->set_name(d.payload_name);
274 decoder->set_payload_type(d.payload_type);
275 }
terelius4311ba52016-04-22 12:40:37 -0700276 if (!event_queue_.Insert(&event)) {
277 LOG(LS_WARNING) << "Config queue full. Not logging config event.";
278 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200279}
280
281void RtcEventLogImpl::LogVideoSendStreamConfig(
282 const VideoSendStream::Config& config) {
terelius4311ba52016-04-22 12:40:37 -0700283 std::unique_ptr<rtclog::Event> event(new rtclog::Event());
284 event->set_timestamp_us(clock_->TimeInMicroseconds());
285 event->set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
Bjorn Terelius36411852015-07-30 12:45:18 +0200286
terelius4311ba52016-04-22 12:40:37 -0700287 rtclog::VideoSendConfig* sender_config = event->mutable_video_sender_config();
Bjorn Terelius36411852015-07-30 12:45:18 +0200288
289 for (const auto& ssrc : config.rtp.ssrcs) {
290 sender_config->add_ssrcs(ssrc);
291 }
292
293 for (const auto& e : config.rtp.extensions) {
294 rtclog::RtpHeaderExtension* extension =
295 sender_config->add_header_extensions();
296 extension->set_name(e.name);
297 extension->set_id(e.id);
298 }
299
300 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) {
301 sender_config->add_rtx_ssrcs(rtx_ssrc);
302 }
303 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type);
304
Bjorn Terelius36411852015-07-30 12:45:18 +0200305 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
306 encoder->set_name(config.encoder_settings.payload_name);
307 encoder->set_payload_type(config.encoder_settings.payload_type);
terelius4311ba52016-04-22 12:40:37 -0700308 if (!event_queue_.Insert(&event)) {
309 LOG(LS_WARNING) << "Config queue full. Not logging config event.";
310 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200311}
312
terelius429c3452016-01-21 05:42:04 -0800313void RtcEventLogImpl::LogRtpHeader(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +0200314 MediaType media_type,
315 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -0700316 size_t packet_length) {
317 // Read header length (in bytes) from packet data.
318 if (packet_length < 12u) {
319 return; // Don't read outside the packet.
320 }
321 const bool x = (header[0] & 0x10) != 0;
322 const uint8_t cc = header[0] & 0x0f;
323 size_t header_length = 12u + cc * 4u;
324
325 if (x) {
326 if (packet_length < 12u + cc * 4u + 4u) {
327 return; // Don't read outside the packet.
328 }
329 size_t x_len = ByteReader<uint16_t>::ReadBigEndian(header + 14 + cc * 4);
330 header_length += (x_len + 1) * 4;
331 }
332
terelius4311ba52016-04-22 12:40:37 -0700333 std::unique_ptr<rtclog::Event> rtp_event(new rtclog::Event());
334 rtp_event->set_timestamp_us(clock_->TimeInMicroseconds());
335 rtp_event->set_type(rtclog::Event::RTP_EVENT);
336 rtp_event->mutable_rtp_packet()->set_incoming(direction == kIncomingPacket);
337 rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type));
338 rtp_event->mutable_rtp_packet()->set_packet_length(packet_length);
339 rtp_event->mutable_rtp_packet()->set_header(header, header_length);
340 if (!event_queue_.Insert(&rtp_event)) {
341 LOG(LS_WARNING) << "RTP queue full. Not logging RTP packet.";
342 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200343}
344
terelius429c3452016-01-21 05:42:04 -0800345void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction,
Bjorn Terelius36411852015-07-30 12:45:18 +0200346 MediaType media_type,
347 const uint8_t* packet,
348 size_t length) {
terelius4311ba52016-04-22 12:40:37 -0700349 std::unique_ptr<rtclog::Event> rtcp_event(new rtclog::Event());
350 rtcp_event->set_timestamp_us(clock_->TimeInMicroseconds());
351 rtcp_event->set_type(rtclog::Event::RTCP_EVENT);
352 rtcp_event->mutable_rtcp_packet()->set_incoming(direction == kIncomingPacket);
353 rtcp_event->mutable_rtcp_packet()->set_type(ConvertMediaType(media_type));
tereliusd66daa22015-11-06 09:00:18 -0800354
355 RTCPUtility::RtcpCommonHeader header;
356 const uint8_t* block_begin = packet;
357 const uint8_t* packet_end = packet + length;
358 RTC_DCHECK(length <= IP_PACKET_SIZE);
359 uint8_t buffer[IP_PACKET_SIZE];
360 uint32_t buffer_length = 0;
361 while (block_begin < packet_end) {
362 if (!RtcpParseCommonHeader(block_begin, packet_end - block_begin,
363 &header)) {
364 break; // Incorrect message header.
365 }
366 uint32_t block_size = header.BlockSize();
367 switch (header.packet_type) {
368 case RTCPUtility::PT_SR:
369 FALLTHROUGH();
370 case RTCPUtility::PT_RR:
371 FALLTHROUGH();
372 case RTCPUtility::PT_BYE:
373 FALLTHROUGH();
374 case RTCPUtility::PT_IJ:
375 FALLTHROUGH();
376 case RTCPUtility::PT_RTPFB:
377 FALLTHROUGH();
378 case RTCPUtility::PT_PSFB:
379 FALLTHROUGH();
380 case RTCPUtility::PT_XR:
381 // We log sender reports, receiver reports, bye messages
382 // inter-arrival jitter, third-party loss reports, payload-specific
383 // feedback and extended reports.
384 memcpy(buffer + buffer_length, block_begin, block_size);
385 buffer_length += block_size;
386 break;
387 case RTCPUtility::PT_SDES:
388 FALLTHROUGH();
389 case RTCPUtility::PT_APP:
390 FALLTHROUGH();
391 default:
392 // We don't log sender descriptions, application defined messages
393 // or message blocks of unknown type.
394 break;
395 }
396
397 block_begin += block_size;
398 }
terelius4311ba52016-04-22 12:40:37 -0700399 rtcp_event->mutable_rtcp_packet()->set_packet_data(buffer, buffer_length);
400 if (!event_queue_.Insert(&rtcp_event)) {
401 LOG(LS_WARNING) << "RTCP queue full. Not logging RTCP packet.";
402 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200403}
404
Ivo Creusenae856f22015-09-17 16:30:16 +0200405void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) {
terelius4311ba52016-04-22 12:40:37 -0700406 std::unique_ptr<rtclog::Event> event(new rtclog::Event());
407 event->set_timestamp_us(clock_->TimeInMicroseconds());
408 event->set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
409 auto playout_event = event->mutable_audio_playout_event();
Ivo Creusen301aaed2015-10-08 18:07:41 +0200410 playout_event->set_local_ssrc(ssrc);
terelius4311ba52016-04-22 12:40:37 -0700411 if (!event_queue_.Insert(&event)) {
412 LOG(LS_WARNING) << "Playout queue full. Not logging ACM playout.";
413 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200414}
415
terelius006d93d2015-11-05 12:02:15 -0800416void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate,
417 uint8_t fraction_loss,
418 int32_t total_packets) {
terelius4311ba52016-04-22 12:40:37 -0700419 std::unique_ptr<rtclog::Event> event(new rtclog::Event());
420 event->set_timestamp_us(clock_->TimeInMicroseconds());
421 event->set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT);
422 auto bwe_event = event->mutable_bwe_packet_loss_event();
terelius006d93d2015-11-05 12:02:15 -0800423 bwe_event->set_bitrate(bitrate);
424 bwe_event->set_fraction_loss(fraction_loss);
425 bwe_event->set_total_packets(total_packets);
terelius4311ba52016-04-22 12:40:37 -0700426 if (!event_queue_.Insert(&event)) {
427 LOG(LS_WARNING) << "BWE loss queue full. Not logging BWE update.";
Bjorn Terelius36411852015-07-30 12:45:18 +0200428 }
429}
430
431bool RtcEventLog::ParseRtcEventLog(const std::string& file_name,
432 rtclog::EventStream* result) {
433 char tmp_buffer[1024];
434 int bytes_read = 0;
kwibergb25345e2016-03-12 06:10:44 -0800435 std::unique_ptr<FileWrapper> dump_file(FileWrapper::Create());
Bjorn Terelius36411852015-07-30 12:45:18 +0200436 if (dump_file->OpenFile(file_name.c_str(), true) != 0) {
437 return false;
438 }
439 std::string dump_buffer;
440 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) {
441 dump_buffer.append(tmp_buffer, bytes_read);
442 }
443 dump_file->CloseFile();
444 return result->ParseFromString(dump_buffer);
445}
446
447#endif // ENABLE_RTC_EVENT_LOG
448
449// RtcEventLog member functions.
terelius4311ba52016-04-22 12:40:37 -0700450std::unique_ptr<RtcEventLog> RtcEventLog::Create(const Clock* clock) {
451#ifdef ENABLE_RTC_EVENT_LOG
452 return std::unique_ptr<RtcEventLog>(new RtcEventLogImpl(clock));
453#else
454 return std::unique_ptr<RtcEventLog>(new RtcEventLogNullImpl());
455#endif // ENABLE_RTC_EVENT_LOG
Bjorn Terelius36411852015-07-30 12:45:18 +0200456}
terelius1adce142015-10-16 08:51:08 -0700457
Bjorn Terelius36411852015-07-30 12:45:18 +0200458} // namespace webrtc