blob: abc2eb47090c69ea8b8798f5f921df40297c52cf [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
13#include <deque>
terelius1adce142015-10-16 08:51:08 -070014#include <vector>
Bjorn Terelius36411852015-07-30 12:45:18 +020015
16#include "webrtc/base/checks.h"
17#include "webrtc/base/criticalsection.h"
18#include "webrtc/base/thread_annotations.h"
19#include "webrtc/call.h"
terelius2f9fd5d2015-09-04 03:39:42 -070020#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010021#include "webrtc/system_wrappers/include/clock.h"
22#include "webrtc/system_wrappers/include/file_wrapper.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020023
24#ifdef ENABLE_RTC_EVENT_LOG
25// Files generated at build-time by the protobuf compiler.
26#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
Peter Boström5c389d32015-09-25 13:58:30 +020027#include "external/webrtc/webrtc/call/rtc_event_log.pb.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020028#else
Peter Boström5c389d32015-09-25 13:58:30 +020029#include "webrtc/call/rtc_event_log.pb.h"
Bjorn Terelius36411852015-07-30 12:45:18 +020030#endif
31#endif
32
33namespace webrtc {
34
35#ifndef ENABLE_RTC_EVENT_LOG
36
37// No-op implementation if flag is not set.
38class RtcEventLogImpl final : public RtcEventLog {
39 public:
terelius1adce142015-10-16 08:51:08 -070040 void SetBufferDuration(int64_t buffer_duration_us) override {}
Bjorn Terelius36411852015-07-30 12:45:18 +020041 void StartLogging(const std::string& file_name, int duration_ms) override {}
ivoc112a3d82015-10-16 02:22:18 -070042 bool StartLogging(rtc::PlatformFile log_file) override { return false; }
Bjorn Terelius36411852015-07-30 12:45:18 +020043 void StopLogging(void) override {}
44 void LogVideoReceiveStreamConfig(
45 const VideoReceiveStream::Config& config) override {}
46 void LogVideoSendStreamConfig(
47 const VideoSendStream::Config& config) override {}
48 void LogRtpHeader(bool incoming,
49 MediaType media_type,
50 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -070051 size_t packet_length) override {}
Bjorn Terelius36411852015-07-30 12:45:18 +020052 void LogRtcpPacket(bool incoming,
53 MediaType media_type,
54 const uint8_t* packet,
55 size_t length) override {}
Ivo Creusenae856f22015-09-17 16:30:16 +020056 void LogAudioPlayout(uint32_t ssrc) override {}
terelius006d93d2015-11-05 12:02:15 -080057 void LogBwePacketLossEvent(int32_t bitrate,
58 uint8_t fraction_loss,
59 int32_t total_packets) override {}
Bjorn Terelius36411852015-07-30 12:45:18 +020060};
61
62#else // ENABLE_RTC_EVENT_LOG is defined
63
64class RtcEventLogImpl final : public RtcEventLog {
65 public:
terelius1adce142015-10-16 08:51:08 -070066 RtcEventLogImpl();
67
68 void SetBufferDuration(int64_t buffer_duration_us) override;
Bjorn Terelius36411852015-07-30 12:45:18 +020069 void StartLogging(const std::string& file_name, int duration_ms) override;
ivoc112a3d82015-10-16 02:22:18 -070070 bool StartLogging(rtc::PlatformFile log_file) override;
Bjorn Terelius36411852015-07-30 12:45:18 +020071 void StopLogging() override;
72 void LogVideoReceiveStreamConfig(
73 const VideoReceiveStream::Config& config) override;
74 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override;
75 void LogRtpHeader(bool incoming,
76 MediaType media_type,
77 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -070078 size_t packet_length) override;
Bjorn Terelius36411852015-07-30 12:45:18 +020079 void LogRtcpPacket(bool incoming,
80 MediaType media_type,
81 const uint8_t* packet,
82 size_t length) override;
Ivo Creusenae856f22015-09-17 16:30:16 +020083 void LogAudioPlayout(uint32_t ssrc) override;
terelius006d93d2015-11-05 12:02:15 -080084 void LogBwePacketLossEvent(int32_t bitrate,
85 uint8_t fraction_loss,
86 int32_t total_packets) override;
Bjorn Terelius36411852015-07-30 12:45:18 +020087
88 private:
ivoc112a3d82015-10-16 02:22:18 -070089 // Starts logging. This function assumes the file_ has been opened succesfully
90 // and that the start_time_us_ and _duration_us_ have been set.
91 void StartLoggingLocked() EXCLUSIVE_LOCKS_REQUIRED(crit_);
Bjorn Terelius36411852015-07-30 12:45:18 +020092 // Stops logging and clears the stored data and buffers.
93 void StopLoggingLocked() EXCLUSIVE_LOCKS_REQUIRED(crit_);
94 // Adds a new event to the logfile if logging is active, or adds it to the
95 // list of recent log events otherwise.
96 void HandleEvent(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_);
97 // Writes the event to the file. Note that this will destroy the state of the
98 // input argument.
99 void StoreToFile(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_);
100 // Adds the event to the list of recent events, and removes any events that
101 // are too old and no longer fall in the time window.
102 void AddRecentEvent(const rtclog::Event& event)
103 EXCLUSIVE_LOCKS_REQUIRED(crit_);
104
Bjorn Terelius36411852015-07-30 12:45:18 +0200105 rtc::CriticalSection crit_;
ivoc112a3d82015-10-16 02:22:18 -0700106 rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_) =
107 rtc::scoped_ptr<FileWrapper>(FileWrapper::Create());
108 rtc::PlatformFile platform_file_ GUARDED_BY(crit_) =
109 rtc::kInvalidPlatformFileValue;
Bjorn Terelius36411852015-07-30 12:45:18 +0200110 rtclog::EventStream stream_ GUARDED_BY(crit_);
111 std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_);
terelius1adce142015-10-16 08:51:08 -0700112 std::vector<rtclog::Event> config_events_ GUARDED_BY(crit_);
113
114 // Microseconds to record log events, before starting the actual log.
115 int64_t buffer_duration_us_ GUARDED_BY(crit_);
116 bool currently_logging_ GUARDED_BY(crit_);
117 int64_t start_time_us_ GUARDED_BY(crit_);
118 int64_t duration_us_ GUARDED_BY(crit_);
119 const Clock* const clock_;
Bjorn Terelius36411852015-07-30 12:45:18 +0200120};
121
122namespace {
123// The functions in this namespace convert enums from the runtime format
124// that the rest of the WebRtc project can use, to the corresponding
125// serialized enum which is defined by the protobuf.
126
127// Do not add default return values to the conversion functions in this
128// unnamed namespace. The intention is to make the compiler warn if anyone
129// adds unhandled new events/modes/etc.
130
pbosda903ea2015-10-02 02:36:56 -0700131rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
Bjorn Terelius36411852015-07-30 12:45:18 +0200132 switch (rtcp_mode) {
pbosda903ea2015-10-02 02:36:56 -0700133 case RtcpMode::kCompound:
Bjorn Terelius36411852015-07-30 12:45:18 +0200134 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
pbosda903ea2015-10-02 02:36:56 -0700135 case RtcpMode::kReducedSize:
Bjorn Terelius36411852015-07-30 12:45:18 +0200136 return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE;
pbosda903ea2015-10-02 02:36:56 -0700137 case RtcpMode::kOff:
138 RTC_NOTREACHED();
139 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
Bjorn Terelius36411852015-07-30 12:45:18 +0200140 }
141 RTC_NOTREACHED();
142 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
143}
144
145rtclog::MediaType ConvertMediaType(MediaType media_type) {
146 switch (media_type) {
147 case MediaType::ANY:
148 return rtclog::MediaType::ANY;
149 case MediaType::AUDIO:
150 return rtclog::MediaType::AUDIO;
151 case MediaType::VIDEO:
152 return rtclog::MediaType::VIDEO;
153 case MediaType::DATA:
154 return rtclog::MediaType::DATA;
155 }
156 RTC_NOTREACHED();
157 return rtclog::ANY;
158}
159
160} // namespace
161
terelius1adce142015-10-16 08:51:08 -0700162namespace {
163bool IsConfigEvent(const rtclog::Event& event) {
164 rtclog::Event_EventType event_type = event.type();
165 return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT ||
166 event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT ||
167 event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT ||
168 event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT;
169}
170} // namespace
171
Bjorn Terelius36411852015-07-30 12:45:18 +0200172// RtcEventLogImpl member functions.
terelius1adce142015-10-16 08:51:08 -0700173RtcEventLogImpl::RtcEventLogImpl()
174 : file_(FileWrapper::Create()),
175 stream_(),
176 buffer_duration_us_(10000000),
177 currently_logging_(false),
178 start_time_us_(0),
179 duration_us_(0),
180 clock_(Clock::GetRealTimeClock()) {
181}
182
183void RtcEventLogImpl::SetBufferDuration(int64_t buffer_duration_us) {
184 rtc::CritScope lock(&crit_);
185 buffer_duration_us_ = buffer_duration_us;
186}
Bjorn Terelius36411852015-07-30 12:45:18 +0200187
188void RtcEventLogImpl::StartLogging(const std::string& file_name,
189 int duration_ms) {
190 rtc::CritScope lock(&crit_);
191 if (currently_logging_) {
192 StopLoggingLocked();
193 }
194 if (file_->OpenFile(file_name.c_str(), false) != 0) {
195 return;
196 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200197 start_time_us_ = clock_->TimeInMicroseconds();
198 duration_us_ = static_cast<int64_t>(duration_ms) * 1000;
ivoc112a3d82015-10-16 02:22:18 -0700199 StartLoggingLocked();
200}
201
202bool RtcEventLogImpl::StartLogging(rtc::PlatformFile log_file) {
203 rtc::CritScope lock(&crit_);
204
205 if (currently_logging_) {
206 StopLoggingLocked();
207 }
208 RTC_DCHECK(platform_file_ == rtc::kInvalidPlatformFileValue);
209
210 FILE* file_stream = rtc::FdopenPlatformFileForWriting(log_file);
211 if (!file_stream) {
212 rtc::ClosePlatformFile(log_file);
213 return false;
214 }
215
216 if (file_->OpenFromFileHandle(file_stream, true, false) != 0) {
217 rtc::ClosePlatformFile(log_file);
218 return false;
219 }
220 platform_file_ = log_file;
221 // Set the start time and duration to keep logging for 10 minutes.
222 start_time_us_ = clock_->TimeInMicroseconds();
223 duration_us_ = 10 * 60 * 1000000;
224 StartLoggingLocked();
225 return true;
226}
227
228void RtcEventLogImpl::StartLoggingLocked() {
229 currently_logging_ = true;
terelius1adce142015-10-16 08:51:08 -0700230
231 // Write all old configuration events to the log file.
232 for (auto& event : config_events_) {
233 StoreToFile(&event);
234 }
235 // Write all recent configuration events to the log file, and
236 // write all other recent events to the log file, ignoring any old events.
Bjorn Terelius36411852015-07-30 12:45:18 +0200237 for (auto& event : recent_log_events_) {
terelius1adce142015-10-16 08:51:08 -0700238 if (IsConfigEvent(event)) {
239 StoreToFile(&event);
240 config_events_.push_back(event);
241 } else if (event.timestamp_us() >= start_time_us_ - buffer_duration_us_) {
Bjorn Terelius36411852015-07-30 12:45:18 +0200242 StoreToFile(&event);
243 }
244 }
245 recent_log_events_.clear();
246 // Write a LOG_START event to the file.
247 rtclog::Event start_event;
248 start_event.set_timestamp_us(start_time_us_);
Ivo Creusen301aaed2015-10-08 18:07:41 +0200249 start_event.set_type(rtclog::Event::LOG_START);
Bjorn Terelius36411852015-07-30 12:45:18 +0200250 StoreToFile(&start_event);
251}
252
253void RtcEventLogImpl::StopLogging() {
254 rtc::CritScope lock(&crit_);
255 StopLoggingLocked();
256}
257
258void RtcEventLogImpl::LogVideoReceiveStreamConfig(
259 const VideoReceiveStream::Config& config) {
260 rtc::CritScope lock(&crit_);
261
262 rtclog::Event event;
terelius006d93d2015-11-05 12:02:15 -0800263 event.set_timestamp_us(clock_->TimeInMicroseconds());
Bjorn Terelius36411852015-07-30 12:45:18 +0200264 event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
265
266 rtclog::VideoReceiveConfig* receiver_config =
267 event.mutable_video_receiver_config();
268 receiver_config->set_remote_ssrc(config.rtp.remote_ssrc);
269 receiver_config->set_local_ssrc(config.rtp.local_ssrc);
270
271 receiver_config->set_rtcp_mode(ConvertRtcpMode(config.rtp.rtcp_mode));
272
273 receiver_config->set_receiver_reference_time_report(
274 config.rtp.rtcp_xr.receiver_reference_time_report);
275 receiver_config->set_remb(config.rtp.remb);
276
277 for (const auto& kv : config.rtp.rtx) {
278 rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
279 rtx->set_payload_type(kv.first);
280 rtx->mutable_config()->set_rtx_ssrc(kv.second.ssrc);
281 rtx->mutable_config()->set_rtx_payload_type(kv.second.payload_type);
282 }
283
284 for (const auto& e : config.rtp.extensions) {
285 rtclog::RtpHeaderExtension* extension =
286 receiver_config->add_header_extensions();
287 extension->set_name(e.name);
288 extension->set_id(e.id);
289 }
290
291 for (const auto& d : config.decoders) {
292 rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
293 decoder->set_name(d.payload_name);
294 decoder->set_payload_type(d.payload_type);
295 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200296 HandleEvent(&event);
297}
298
299void RtcEventLogImpl::LogVideoSendStreamConfig(
300 const VideoSendStream::Config& config) {
301 rtc::CritScope lock(&crit_);
302
303 rtclog::Event event;
terelius006d93d2015-11-05 12:02:15 -0800304 event.set_timestamp_us(clock_->TimeInMicroseconds());
Bjorn Terelius36411852015-07-30 12:45:18 +0200305 event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
306
307 rtclog::VideoSendConfig* sender_config = event.mutable_video_sender_config();
308
309 for (const auto& ssrc : config.rtp.ssrcs) {
310 sender_config->add_ssrcs(ssrc);
311 }
312
313 for (const auto& e : config.rtp.extensions) {
314 rtclog::RtpHeaderExtension* extension =
315 sender_config->add_header_extensions();
316 extension->set_name(e.name);
317 extension->set_id(e.id);
318 }
319
320 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) {
321 sender_config->add_rtx_ssrcs(rtx_ssrc);
322 }
323 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type);
324
325 sender_config->set_c_name(config.rtp.c_name);
326
327 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
328 encoder->set_name(config.encoder_settings.payload_name);
329 encoder->set_payload_type(config.encoder_settings.payload_type);
Bjorn Terelius36411852015-07-30 12:45:18 +0200330 HandleEvent(&event);
331}
332
Bjorn Terelius36411852015-07-30 12:45:18 +0200333void RtcEventLogImpl::LogRtpHeader(bool incoming,
334 MediaType media_type,
335 const uint8_t* header,
terelius2f9fd5d2015-09-04 03:39:42 -0700336 size_t packet_length) {
337 // Read header length (in bytes) from packet data.
338 if (packet_length < 12u) {
339 return; // Don't read outside the packet.
340 }
341 const bool x = (header[0] & 0x10) != 0;
342 const uint8_t cc = header[0] & 0x0f;
343 size_t header_length = 12u + cc * 4u;
344
345 if (x) {
346 if (packet_length < 12u + cc * 4u + 4u) {
347 return; // Don't read outside the packet.
348 }
349 size_t x_len = ByteReader<uint16_t>::ReadBigEndian(header + 14 + cc * 4);
350 header_length += (x_len + 1) * 4;
351 }
352
Bjorn Terelius36411852015-07-30 12:45:18 +0200353 rtc::CritScope lock(&crit_);
354 rtclog::Event rtp_event;
terelius006d93d2015-11-05 12:02:15 -0800355 rtp_event.set_timestamp_us(clock_->TimeInMicroseconds());
Bjorn Terelius36411852015-07-30 12:45:18 +0200356 rtp_event.set_type(rtclog::Event::RTP_EVENT);
357 rtp_event.mutable_rtp_packet()->set_incoming(incoming);
358 rtp_event.mutable_rtp_packet()->set_type(ConvertMediaType(media_type));
terelius2f9fd5d2015-09-04 03:39:42 -0700359 rtp_event.mutable_rtp_packet()->set_packet_length(packet_length);
Bjorn Terelius36411852015-07-30 12:45:18 +0200360 rtp_event.mutable_rtp_packet()->set_header(header, header_length);
361 HandleEvent(&rtp_event);
362}
363
364void RtcEventLogImpl::LogRtcpPacket(bool incoming,
365 MediaType media_type,
366 const uint8_t* packet,
367 size_t length) {
368 rtc::CritScope lock(&crit_);
369 rtclog::Event rtcp_event;
terelius006d93d2015-11-05 12:02:15 -0800370 rtcp_event.set_timestamp_us(clock_->TimeInMicroseconds());
Bjorn Terelius36411852015-07-30 12:45:18 +0200371 rtcp_event.set_type(rtclog::Event::RTCP_EVENT);
372 rtcp_event.mutable_rtcp_packet()->set_incoming(incoming);
373 rtcp_event.mutable_rtcp_packet()->set_type(ConvertMediaType(media_type));
374 rtcp_event.mutable_rtcp_packet()->set_packet_data(packet, length);
375 HandleEvent(&rtcp_event);
376}
377
Ivo Creusenae856f22015-09-17 16:30:16 +0200378void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) {
Bjorn Terelius36411852015-07-30 12:45:18 +0200379 rtc::CritScope lock(&crit_);
380 rtclog::Event event;
terelius006d93d2015-11-05 12:02:15 -0800381 event.set_timestamp_us(clock_->TimeInMicroseconds());
Ivo Creusen301aaed2015-10-08 18:07:41 +0200382 event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
383 auto playout_event = event.mutable_audio_playout_event();
384 playout_event->set_local_ssrc(ssrc);
Bjorn Terelius36411852015-07-30 12:45:18 +0200385 HandleEvent(&event);
386}
387
terelius006d93d2015-11-05 12:02:15 -0800388void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate,
389 uint8_t fraction_loss,
390 int32_t total_packets) {
391 rtc::CritScope lock(&crit_);
392 rtclog::Event event;
393 event.set_timestamp_us(clock_->TimeInMicroseconds());
394 event.set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT);
395 auto bwe_event = event.mutable_bwe_packet_loss_event();
396 bwe_event->set_bitrate(bitrate);
397 bwe_event->set_fraction_loss(fraction_loss);
398 bwe_event->set_total_packets(total_packets);
399 HandleEvent(&event);
400}
401
Bjorn Terelius36411852015-07-30 12:45:18 +0200402void RtcEventLogImpl::StopLoggingLocked() {
403 if (currently_logging_) {
404 currently_logging_ = false;
Ivo Creusen301aaed2015-10-08 18:07:41 +0200405 // Create a LogEnd event
Bjorn Terelius36411852015-07-30 12:45:18 +0200406 rtclog::Event event;
terelius006d93d2015-11-05 12:02:15 -0800407 event.set_timestamp_us(clock_->TimeInMicroseconds());
Ivo Creusen301aaed2015-10-08 18:07:41 +0200408 event.set_type(rtclog::Event::LOG_END);
Bjorn Terelius36411852015-07-30 12:45:18 +0200409 // Store the event and close the file
henrikg91d6ede2015-09-17 00:24:34 -0700410 RTC_DCHECK(file_->Open());
Bjorn Terelius36411852015-07-30 12:45:18 +0200411 StoreToFile(&event);
412 file_->CloseFile();
ivoc112a3d82015-10-16 02:22:18 -0700413 if (platform_file_ != rtc::kInvalidPlatformFileValue) {
414 rtc::ClosePlatformFile(platform_file_);
415 platform_file_ = rtc::kInvalidPlatformFileValue;
416 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200417 }
henrikg91d6ede2015-09-17 00:24:34 -0700418 RTC_DCHECK(!file_->Open());
Bjorn Terelius36411852015-07-30 12:45:18 +0200419 stream_.Clear();
420}
421
422void RtcEventLogImpl::HandleEvent(rtclog::Event* event) {
423 if (currently_logging_) {
424 if (clock_->TimeInMicroseconds() < start_time_us_ + duration_us_) {
425 StoreToFile(event);
426 return;
427 }
428 StopLoggingLocked();
429 }
430 AddRecentEvent(*event);
431}
432
433void RtcEventLogImpl::StoreToFile(rtclog::Event* event) {
434 // Reuse the same object at every log event.
435 if (stream_.stream_size() < 1) {
436 stream_.add_stream();
437 }
henrikg91d6ede2015-09-17 00:24:34 -0700438 RTC_DCHECK_EQ(stream_.stream_size(), 1);
Bjorn Terelius36411852015-07-30 12:45:18 +0200439 stream_.mutable_stream(0)->Swap(event);
440 // TODO(terelius): Doesn't this create a new EventStream per event?
441 // Is this guaranteed to work e.g. in future versions of protobuf?
442 std::string dump_buffer;
443 stream_.SerializeToString(&dump_buffer);
444 file_->Write(dump_buffer.data(), dump_buffer.size());
445}
446
447void RtcEventLogImpl::AddRecentEvent(const rtclog::Event& event) {
448 recent_log_events_.push_back(event);
449 while (recent_log_events_.front().timestamp_us() <
terelius1adce142015-10-16 08:51:08 -0700450 event.timestamp_us() - buffer_duration_us_) {
451 if (IsConfigEvent(recent_log_events_.front())) {
452 config_events_.push_back(recent_log_events_.front());
453 }
Bjorn Terelius36411852015-07-30 12:45:18 +0200454 recent_log_events_.pop_front();
455 }
456}
457
458bool RtcEventLog::ParseRtcEventLog(const std::string& file_name,
459 rtclog::EventStream* result) {
460 char tmp_buffer[1024];
461 int bytes_read = 0;
462 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create());
463 if (dump_file->OpenFile(file_name.c_str(), true) != 0) {
464 return false;
465 }
466 std::string dump_buffer;
467 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) {
468 dump_buffer.append(tmp_buffer, bytes_read);
469 }
470 dump_file->CloseFile();
471 return result->ParseFromString(dump_buffer);
472}
473
474#endif // ENABLE_RTC_EVENT_LOG
475
476// RtcEventLog member functions.
477rtc::scoped_ptr<RtcEventLog> RtcEventLog::Create() {
478 return rtc::scoped_ptr<RtcEventLog>(new RtcEventLogImpl());
479}
terelius1adce142015-10-16 08:51:08 -0700480
Bjorn Terelius36411852015-07-30 12:45:18 +0200481} // namespace webrtc