OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 void LogRtcpPacket(PacketDirection direction, | 96 void LogRtcpPacket(PacketDirection direction, |
97 MediaType media_type, | 97 MediaType media_type, |
98 const uint8_t* packet, | 98 const uint8_t* packet, |
99 size_t length) override; | 99 size_t length) override; |
100 void LogAudioPlayout(uint32_t ssrc) override; | 100 void LogAudioPlayout(uint32_t ssrc) override; |
101 void LogBwePacketLossEvent(int32_t bitrate, | 101 void LogBwePacketLossEvent(int32_t bitrate, |
102 uint8_t fraction_loss, | 102 uint8_t fraction_loss, |
103 int32_t total_packets) override; | 103 int32_t total_packets) override; |
104 | 104 |
105 private: | 105 private: |
106 void StoreEvent(std::unique_ptr<rtclog::Event>* event); | |
107 | |
106 // Message queue for passing control messages to the logging thread. | 108 // Message queue for passing control messages to the logging thread. |
107 SwapQueue<RtcEventLogHelperThread::ControlMessage> message_queue_; | 109 SwapQueue<RtcEventLogHelperThread::ControlMessage> message_queue_; |
108 | 110 |
109 // Message queue for passing events to the logging thread. | 111 // Message queue for passing events to the logging thread. |
110 SwapQueue<std::unique_ptr<rtclog::Event> > event_queue_; | 112 SwapQueue<std::unique_ptr<rtclog::Event> > event_queue_; |
111 | 113 |
112 rtc::Event wake_up_; | 114 rtc::Event wake_up_; |
115 rtc::Event end_hibernation_; | |
113 rtc::Event stopped_; | 116 rtc::Event stopped_; |
114 | 117 |
115 const Clock* const clock_; | 118 const Clock* const clock_; |
116 | 119 |
117 RtcEventLogHelperThread helper_thread_; | 120 RtcEventLogHelperThread helper_thread_; |
118 rtc::ThreadChecker thread_checker_; | 121 rtc::ThreadChecker thread_checker_; |
119 | 122 |
120 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtcEventLogImpl); | 123 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtcEventLogImpl); |
121 }; | 124 }; |
122 | 125 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 static const int kEventsPerSecond = 1000; | 162 static const int kEventsPerSecond = 1000; |
160 static const int kControlMessagesPerSecond = 10; | 163 static const int kControlMessagesPerSecond = 10; |
161 } // namespace | 164 } // namespace |
162 | 165 |
163 // RtcEventLogImpl member functions. | 166 // RtcEventLogImpl member functions. |
164 RtcEventLogImpl::RtcEventLogImpl(const Clock* clock) | 167 RtcEventLogImpl::RtcEventLogImpl(const Clock* clock) |
165 // Allocate buffers for roughly one second of history. | 168 // Allocate buffers for roughly one second of history. |
166 : message_queue_(kControlMessagesPerSecond), | 169 : message_queue_(kControlMessagesPerSecond), |
167 event_queue_(kEventsPerSecond), | 170 event_queue_(kEventsPerSecond), |
168 wake_up_(false, false), | 171 wake_up_(false, false), |
172 end_hibernation_(false, false), | |
169 stopped_(false, false), | 173 stopped_(false, false), |
170 clock_(clock), | 174 clock_(clock), |
171 helper_thread_(&message_queue_, | 175 helper_thread_(&message_queue_, |
172 &event_queue_, | 176 &event_queue_, |
173 &wake_up_, | 177 &wake_up_, |
178 &end_hibernation_, | |
174 &stopped_, | 179 &stopped_, |
175 clock), | 180 clock), |
176 thread_checker_() { | 181 thread_checker_() { |
177 thread_checker_.DetachFromThread(); | 182 thread_checker_.DetachFromThread(); |
178 } | 183 } |
179 | 184 |
180 RtcEventLogImpl::~RtcEventLogImpl() { | 185 RtcEventLogImpl::~RtcEventLogImpl() { |
181 // The RtcEventLogHelperThread destructor closes the file | 186 // The RtcEventLogHelperThread destructor closes the file |
182 // and waits for the thread to terminate. | 187 // and waits for the thread to terminate. |
183 } | 188 } |
(...skipping 10 matching lines...) Expand all Loading... | |
194 message.stop_time = std::numeric_limits<int64_t>::max(); | 199 message.stop_time = std::numeric_limits<int64_t>::max(); |
195 message.file.reset(FileWrapper::Create()); | 200 message.file.reset(FileWrapper::Create()); |
196 if (message.file->OpenFile(file_name.c_str(), false) != 0) { | 201 if (message.file->OpenFile(file_name.c_str(), false) != 0) { |
197 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; | 202 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; |
198 return false; | 203 return false; |
199 } | 204 } |
200 if (!message_queue_.Insert(&message)) { | 205 if (!message_queue_.Insert(&message)) { |
201 LOG(LS_ERROR) << "Message queue full. Can't start logging."; | 206 LOG(LS_ERROR) << "Message queue full. Can't start logging."; |
202 return false; | 207 return false; |
203 } | 208 } |
209 end_hibernation_.Set(); | |
204 LOG(LS_INFO) << "Starting WebRTC event log."; | 210 LOG(LS_INFO) << "Starting WebRTC event log."; |
205 return true; | 211 return true; |
206 } | 212 } |
207 | 213 |
208 bool RtcEventLogImpl::StartLogging(rtc::PlatformFile platform_file, | 214 bool RtcEventLogImpl::StartLogging(rtc::PlatformFile platform_file, |
209 int64_t max_size_bytes) { | 215 int64_t max_size_bytes) { |
210 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 216 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
211 RtcEventLogHelperThread::ControlMessage message; | 217 RtcEventLogHelperThread::ControlMessage message; |
212 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; | 218 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; |
213 message.max_size_bytes = max_size_bytes <= 0 | 219 message.max_size_bytes = max_size_bytes <= 0 |
(...skipping 13 matching lines...) Expand all Loading... | |
227 return false; | 233 return false; |
228 } | 234 } |
229 if (message.file->OpenFromFileHandle(file_handle, true, false) != 0) { | 235 if (message.file->OpenFromFileHandle(file_handle, true, false) != 0) { |
230 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; | 236 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; |
231 return false; | 237 return false; |
232 } | 238 } |
233 if (!message_queue_.Insert(&message)) { | 239 if (!message_queue_.Insert(&message)) { |
234 LOG(LS_ERROR) << "Message queue full. Can't start logging."; | 240 LOG(LS_ERROR) << "Message queue full. Can't start logging."; |
235 return false; | 241 return false; |
236 } | 242 } |
243 end_hibernation_.Set(); | |
237 LOG(LS_INFO) << "Starting WebRTC event log."; | 244 LOG(LS_INFO) << "Starting WebRTC event log."; |
238 return true; | 245 return true; |
239 } | 246 } |
240 | 247 |
241 void RtcEventLogImpl::StopLogging() { | 248 void RtcEventLogImpl::StopLogging() { |
242 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 249 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
243 RtcEventLogHelperThread::ControlMessage message; | 250 RtcEventLogHelperThread::ControlMessage message; |
244 message.message_type = RtcEventLogHelperThread::ControlMessage::STOP_FILE; | 251 message.message_type = RtcEventLogHelperThread::ControlMessage::STOP_FILE; |
245 message.stop_time = clock_->TimeInMicroseconds(); | 252 message.stop_time = clock_->TimeInMicroseconds(); |
246 while (!message_queue_.Insert(&message)) { | 253 while (!message_queue_.Insert(&message)) { |
247 // TODO(terelius): We would like to have a blocking Insert function in the | 254 // TODO(terelius): We would like to have a blocking Insert function in the |
248 // SwapQueue, but for the time being we will just clear any previous | 255 // SwapQueue, but for the time being we will just clear any previous |
249 // messages. | 256 // messages. |
250 // Since StopLogging waits for the thread, it is essential that we don't | 257 // Since StopLogging waits for the thread, it is essential that we don't |
251 // clear any STOP_FILE messages. To ensure that there is only one call at a | 258 // clear any STOP_FILE messages. To ensure that there is only one call at a |
252 // time, we require that all calls to StopLogging are made on the same | 259 // time, we require that all calls to StopLogging are made on the same |
253 // thread. | 260 // thread. |
254 LOG(LS_ERROR) << "Message queue full. Clearing queue to stop logging."; | 261 LOG(LS_ERROR) << "Message queue full. Clearing queue to stop logging."; |
255 message_queue_.Clear(); | 262 message_queue_.Clear(); |
256 } | 263 } |
257 LOG(LS_INFO) << "Stopping WebRTC event log."; | 264 LOG(LS_INFO) << "Stopping WebRTC event log."; |
265 end_hibernation_.Set(); | |
pbos-webrtc
2016/06/03 08:54:25
Should the last three lines here be replaced with
terelius
2016/06/08 11:47:29
Done. Note that this only reduces the number of sh
| |
258 wake_up_.Set(); // Request the output thread to wake up. | 266 wake_up_.Set(); // Request the output thread to wake up. |
259 stopped_.Wait(rtc::Event::kForever); // Wait for the log to stop. | 267 stopped_.Wait(rtc::Event::kForever); // Wait for the log to stop. |
260 } | 268 } |
261 | 269 |
262 void RtcEventLogImpl::LogVideoReceiveStreamConfig( | 270 void RtcEventLogImpl::LogVideoReceiveStreamConfig( |
263 const VideoReceiveStream::Config& config) { | 271 const VideoReceiveStream::Config& config) { |
264 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 272 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
265 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 273 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
266 event->set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); | 274 event->set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); |
267 | 275 |
(...skipping 17 matching lines...) Expand all Loading... | |
285 receiver_config->add_header_extensions(); | 293 receiver_config->add_header_extensions(); |
286 extension->set_name(e.uri); | 294 extension->set_name(e.uri); |
287 extension->set_id(e.id); | 295 extension->set_id(e.id); |
288 } | 296 } |
289 | 297 |
290 for (const auto& d : config.decoders) { | 298 for (const auto& d : config.decoders) { |
291 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); | 299 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); |
292 decoder->set_name(d.payload_name); | 300 decoder->set_name(d.payload_name); |
293 decoder->set_payload_type(d.payload_type); | 301 decoder->set_payload_type(d.payload_type); |
294 } | 302 } |
295 if (!event_queue_.Insert(&event)) { | 303 StoreEvent(&event); |
296 LOG(LS_ERROR) << "Config queue full. Not logging config event."; | |
297 } | |
298 } | 304 } |
299 | 305 |
300 void RtcEventLogImpl::LogVideoSendStreamConfig( | 306 void RtcEventLogImpl::LogVideoSendStreamConfig( |
301 const VideoSendStream::Config& config) { | 307 const VideoSendStream::Config& config) { |
302 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 308 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
303 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 309 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
304 event->set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); | 310 event->set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); |
305 | 311 |
306 rtclog::VideoSendConfig* sender_config = event->mutable_video_sender_config(); | 312 rtclog::VideoSendConfig* sender_config = event->mutable_video_sender_config(); |
307 | 313 |
308 for (const auto& ssrc : config.rtp.ssrcs) { | 314 for (const auto& ssrc : config.rtp.ssrcs) { |
309 sender_config->add_ssrcs(ssrc); | 315 sender_config->add_ssrcs(ssrc); |
310 } | 316 } |
311 | 317 |
312 for (const auto& e : config.rtp.extensions) { | 318 for (const auto& e : config.rtp.extensions) { |
313 rtclog::RtpHeaderExtension* extension = | 319 rtclog::RtpHeaderExtension* extension = |
314 sender_config->add_header_extensions(); | 320 sender_config->add_header_extensions(); |
315 extension->set_name(e.uri); | 321 extension->set_name(e.uri); |
316 extension->set_id(e.id); | 322 extension->set_id(e.id); |
317 } | 323 } |
318 | 324 |
319 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) { | 325 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) { |
320 sender_config->add_rtx_ssrcs(rtx_ssrc); | 326 sender_config->add_rtx_ssrcs(rtx_ssrc); |
321 } | 327 } |
322 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); | 328 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); |
323 | 329 |
324 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); | 330 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); |
325 encoder->set_name(config.encoder_settings.payload_name); | 331 encoder->set_name(config.encoder_settings.payload_name); |
326 encoder->set_payload_type(config.encoder_settings.payload_type); | 332 encoder->set_payload_type(config.encoder_settings.payload_type); |
327 if (!event_queue_.Insert(&event)) { | 333 StoreEvent(&event); |
328 LOG(LS_ERROR) << "Config queue full. Not logging config event."; | |
329 } | |
330 } | 334 } |
331 | 335 |
332 void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, | 336 void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, |
333 MediaType media_type, | 337 MediaType media_type, |
334 const uint8_t* header, | 338 const uint8_t* header, |
335 size_t packet_length) { | 339 size_t packet_length) { |
336 // Read header length (in bytes) from packet data. | 340 // Read header length (in bytes) from packet data. |
337 if (packet_length < 12u) { | 341 if (packet_length < 12u) { |
338 return; // Don't read outside the packet. | 342 return; // Don't read outside the packet. |
339 } | 343 } |
340 const bool x = (header[0] & 0x10) != 0; | 344 const bool x = (header[0] & 0x10) != 0; |
341 const uint8_t cc = header[0] & 0x0f; | 345 const uint8_t cc = header[0] & 0x0f; |
342 size_t header_length = 12u + cc * 4u; | 346 size_t header_length = 12u + cc * 4u; |
343 | 347 |
344 if (x) { | 348 if (x) { |
345 if (packet_length < 12u + cc * 4u + 4u) { | 349 if (packet_length < 12u + cc * 4u + 4u) { |
346 return; // Don't read outside the packet. | 350 return; // Don't read outside the packet. |
347 } | 351 } |
348 size_t x_len = ByteReader<uint16_t>::ReadBigEndian(header + 14 + cc * 4); | 352 size_t x_len = ByteReader<uint16_t>::ReadBigEndian(header + 14 + cc * 4); |
349 header_length += (x_len + 1) * 4; | 353 header_length += (x_len + 1) * 4; |
350 } | 354 } |
351 | 355 |
352 std::unique_ptr<rtclog::Event> rtp_event(new rtclog::Event()); | 356 std::unique_ptr<rtclog::Event> rtp_event(new rtclog::Event()); |
353 rtp_event->set_timestamp_us(clock_->TimeInMicroseconds()); | 357 rtp_event->set_timestamp_us(clock_->TimeInMicroseconds()); |
354 rtp_event->set_type(rtclog::Event::RTP_EVENT); | 358 rtp_event->set_type(rtclog::Event::RTP_EVENT); |
355 rtp_event->mutable_rtp_packet()->set_incoming(direction == kIncomingPacket); | 359 rtp_event->mutable_rtp_packet()->set_incoming(direction == kIncomingPacket); |
356 rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type)); | 360 rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type)); |
357 rtp_event->mutable_rtp_packet()->set_packet_length(packet_length); | 361 rtp_event->mutable_rtp_packet()->set_packet_length(packet_length); |
358 rtp_event->mutable_rtp_packet()->set_header(header, header_length); | 362 rtp_event->mutable_rtp_packet()->set_header(header, header_length); |
359 if (!event_queue_.Insert(&rtp_event)) { | 363 StoreEvent(&rtp_event); |
360 LOG(LS_ERROR) << "RTP queue full. Not logging RTP packet."; | |
361 } | |
362 } | 364 } |
363 | 365 |
364 void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction, | 366 void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction, |
365 MediaType media_type, | 367 MediaType media_type, |
366 const uint8_t* packet, | 368 const uint8_t* packet, |
367 size_t length) { | 369 size_t length) { |
368 std::unique_ptr<rtclog::Event> rtcp_event(new rtclog::Event()); | 370 std::unique_ptr<rtclog::Event> rtcp_event(new rtclog::Event()); |
369 rtcp_event->set_timestamp_us(clock_->TimeInMicroseconds()); | 371 rtcp_event->set_timestamp_us(clock_->TimeInMicroseconds()); |
370 rtcp_event->set_type(rtclog::Event::RTCP_EVENT); | 372 rtcp_event->set_type(rtclog::Event::RTCP_EVENT); |
371 rtcp_event->mutable_rtcp_packet()->set_incoming(direction == kIncomingPacket); | 373 rtcp_event->mutable_rtcp_packet()->set_incoming(direction == kIncomingPacket); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 FALLTHROUGH(); | 411 FALLTHROUGH(); |
410 default: | 412 default: |
411 // We don't log sender descriptions, application defined messages | 413 // We don't log sender descriptions, application defined messages |
412 // or message blocks of unknown type. | 414 // or message blocks of unknown type. |
413 break; | 415 break; |
414 } | 416 } |
415 | 417 |
416 block_begin += block_size; | 418 block_begin += block_size; |
417 } | 419 } |
418 rtcp_event->mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); | 420 rtcp_event->mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); |
419 if (!event_queue_.Insert(&rtcp_event)) { | 421 StoreEvent(&rtcp_event); |
420 LOG(LS_ERROR) << "RTCP queue full. Not logging RTCP packet."; | |
421 } | |
422 } | 422 } |
423 | 423 |
424 void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) { | 424 void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) { |
425 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 425 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
426 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 426 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
427 event->set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT); | 427 event->set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT); |
428 auto playout_event = event->mutable_audio_playout_event(); | 428 auto playout_event = event->mutable_audio_playout_event(); |
429 playout_event->set_local_ssrc(ssrc); | 429 playout_event->set_local_ssrc(ssrc); |
430 if (!event_queue_.Insert(&event)) { | 430 StoreEvent(&event); |
431 LOG(LS_ERROR) << "Playout queue full. Not logging ACM playout."; | |
432 } | |
433 } | 431 } |
434 | 432 |
435 void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate, | 433 void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate, |
436 uint8_t fraction_loss, | 434 uint8_t fraction_loss, |
437 int32_t total_packets) { | 435 int32_t total_packets) { |
438 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 436 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
439 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 437 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
440 event->set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT); | 438 event->set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT); |
441 auto bwe_event = event->mutable_bwe_packet_loss_event(); | 439 auto bwe_event = event->mutable_bwe_packet_loss_event(); |
442 bwe_event->set_bitrate(bitrate); | 440 bwe_event->set_bitrate(bitrate); |
443 bwe_event->set_fraction_loss(fraction_loss); | 441 bwe_event->set_fraction_loss(fraction_loss); |
444 bwe_event->set_total_packets(total_packets); | 442 bwe_event->set_total_packets(total_packets); |
445 if (!event_queue_.Insert(&event)) { | 443 StoreEvent(&event); |
446 LOG(LS_ERROR) << "BWE loss queue full. Not logging BWE update."; | 444 } |
445 | |
446 void RtcEventLogImpl::StoreEvent(std::unique_ptr<rtclog::Event>* event) { | |
447 if (!event_queue_.Insert(event)) { | |
448 LOG(LS_ERROR) << "WebRTC event log queue full. Dropping event."; | |
447 } | 449 } |
450 end_hibernation_.Set(); | |
448 } | 451 } |
449 | 452 |
450 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, | 453 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, |
451 rtclog::EventStream* result) { | 454 rtclog::EventStream* result) { |
452 char tmp_buffer[1024]; | 455 char tmp_buffer[1024]; |
453 int bytes_read = 0; | 456 int bytes_read = 0; |
454 std::unique_ptr<FileWrapper> dump_file(FileWrapper::Create()); | 457 std::unique_ptr<FileWrapper> dump_file(FileWrapper::Create()); |
455 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { | 458 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { |
456 return false; | 459 return false; |
457 } | 460 } |
(...skipping 10 matching lines...) Expand all Loading... | |
468 // RtcEventLog member functions. | 471 // RtcEventLog member functions. |
469 std::unique_ptr<RtcEventLog> RtcEventLog::Create(const Clock* clock) { | 472 std::unique_ptr<RtcEventLog> RtcEventLog::Create(const Clock* clock) { |
470 #ifdef ENABLE_RTC_EVENT_LOG | 473 #ifdef ENABLE_RTC_EVENT_LOG |
471 return std::unique_ptr<RtcEventLog>(new RtcEventLogImpl(clock)); | 474 return std::unique_ptr<RtcEventLog>(new RtcEventLogImpl(clock)); |
472 #else | 475 #else |
473 return std::unique_ptr<RtcEventLog>(new RtcEventLogNullImpl()); | 476 return std::unique_ptr<RtcEventLog>(new RtcEventLogNullImpl()); |
474 #endif // ENABLE_RTC_EVENT_LOG | 477 #endif // ENABLE_RTC_EVENT_LOG |
475 } | 478 } |
476 | 479 |
477 } // namespace webrtc | 480 } // namespace webrtc |
OLD | NEW |