Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 | 42 |
| 43 // No-op implementation if flag is not set. | 43 // No-op implementation if flag is not set. |
| 44 class RtcEventLogNullImpl final : public RtcEventLog { | 44 class RtcEventLogNullImpl final : public RtcEventLog { |
| 45 public: | 45 public: |
| 46 bool StartLogging(const std::string& file_name, | 46 bool StartLogging(const std::string& file_name, |
| 47 int64_t max_size_bytes) override { | 47 int64_t max_size_bytes) override { |
| 48 return false; | 48 return false; |
| 49 } | 49 } |
| 50 bool StartLogging(rtc::PlatformFile platform_file, | 50 bool StartLogging(rtc::PlatformFile platform_file, |
| 51 int64_t max_size_bytes) override { | 51 int64_t max_size_bytes) override { |
| 52 // The platform_file is open and needs to be closed. | |
| 53 if (!rtc::ClosePlatformFile(platform_file)) { | |
| 54 LOG(LS_ERROR) << "Can't close file."; | |
| 55 } | |
| 52 return false; | 56 return false; |
| 53 } | 57 } |
| 54 void StopLogging() override {} | 58 void StopLogging() override {} |
| 55 void LogVideoReceiveStreamConfig( | 59 void LogVideoReceiveStreamConfig( |
| 56 const VideoReceiveStream::Config& config) override {} | 60 const VideoReceiveStream::Config& config) override {} |
| 57 void LogVideoSendStreamConfig( | 61 void LogVideoSendStreamConfig( |
| 58 const VideoSendStream::Config& config) override {} | 62 const VideoSendStream::Config& config) override {} |
| 59 void LogRtpHeader(PacketDirection direction, | 63 void LogRtpHeader(PacketDirection direction, |
| 60 MediaType media_type, | 64 MediaType media_type, |
| 61 const uint8_t* header, | 65 const uint8_t* header, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 183 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 187 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 184 RtcEventLogHelperThread::ControlMessage message; | 188 RtcEventLogHelperThread::ControlMessage message; |
| 185 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; | 189 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; |
| 186 message.max_size_bytes = max_size_bytes <= 0 | 190 message.max_size_bytes = max_size_bytes <= 0 |
| 187 ? std::numeric_limits<int64_t>::max() | 191 ? std::numeric_limits<int64_t>::max() |
| 188 : max_size_bytes; | 192 : max_size_bytes; |
| 189 message.start_time = clock_->TimeInMicroseconds(); | 193 message.start_time = clock_->TimeInMicroseconds(); |
| 190 message.stop_time = std::numeric_limits<int64_t>::max(); | 194 message.stop_time = std::numeric_limits<int64_t>::max(); |
| 191 message.file.reset(FileWrapper::Create()); | 195 message.file.reset(FileWrapper::Create()); |
| 192 if (message.file->OpenFile(file_name.c_str(), false) != 0) { | 196 if (message.file->OpenFile(file_name.c_str(), false) != 0) { |
| 197 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; | |
| 193 return false; | 198 return false; |
| 194 } | 199 } |
| 195 if (!message_queue_.Insert(&message)) { | 200 if (!message_queue_.Insert(&message)) { |
| 196 LOG(LS_WARNING) << "Message queue full. Can't start logging."; | 201 LOG(LS_ERROR) << "Message queue full. Can't start logging."; |
| 197 return false; | 202 return false; |
| 198 } | 203 } |
| 204 LOG(LS_INFO) << "Starting WebRTC event log."; | |
| 199 return true; | 205 return true; |
| 200 } | 206 } |
| 201 | 207 |
| 202 bool RtcEventLogImpl::StartLogging(rtc::PlatformFile platform_file, | 208 bool RtcEventLogImpl::StartLogging(rtc::PlatformFile platform_file, |
| 203 int64_t max_size_bytes) { | 209 int64_t max_size_bytes) { |
| 204 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 210 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 205 RtcEventLogHelperThread::ControlMessage message; | 211 RtcEventLogHelperThread::ControlMessage message; |
| 206 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; | 212 message.message_type = RtcEventLogHelperThread::ControlMessage::START_FILE; |
| 207 message.max_size_bytes = max_size_bytes <= 0 | 213 message.max_size_bytes = max_size_bytes <= 0 |
| 208 ? std::numeric_limits<int64_t>::max() | 214 ? std::numeric_limits<int64_t>::max() |
| 209 : max_size_bytes; | 215 : max_size_bytes; |
| 210 message.start_time = clock_->TimeInMicroseconds(); | 216 message.start_time = clock_->TimeInMicroseconds(); |
| 211 message.stop_time = std::numeric_limits<int64_t>::max(); | 217 message.stop_time = std::numeric_limits<int64_t>::max(); |
| 212 message.file.reset(FileWrapper::Create()); | 218 message.file.reset(FileWrapper::Create()); |
| 213 FILE* file_handle = rtc::FdopenPlatformFileForWriting(platform_file); | 219 FILE* file_handle = rtc::FdopenPlatformFileForWriting(platform_file); |
| 214 if (!file_handle) { | 220 if (!file_handle) { |
| 221 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; | |
| 222 // Even though we failed to open a FILE*, the platform_file is still open | |
| 223 // and needs to be closed. | |
| 224 if (!rtc::ClosePlatformFile(platform_file)) { | |
| 225 LOG(LS_ERROR) << "Can't close file."; | |
| 226 } | |
| 215 return false; | 227 return false; |
| 216 } | 228 } |
| 217 if (message.file->OpenFromFileHandle(file_handle, true, false) != 0) { | 229 if (message.file->OpenFromFileHandle(file_handle, true, false) != 0) { |
| 230 LOG(LS_ERROR) << "Can't open file. WebRTC event log not started."; | |
| 218 return false; | 231 return false; |
| 219 } | 232 } |
| 220 if (!message_queue_.Insert(&message)) { | 233 if (!message_queue_.Insert(&message)) { |
|
pbos-webrtc
2016/05/26 21:22:40
Side note, should this ever happen? That seems sca
| |
| 221 LOG(LS_WARNING) << "Message queue full. Can't start logging."; | 234 LOG(LS_ERROR) << "Message queue full. Can't start logging."; |
| 222 return false; | 235 return false; |
| 223 } | 236 } |
| 237 LOG(LS_INFO) << "Starting WebRTC event log."; | |
| 224 return true; | 238 return true; |
| 225 } | 239 } |
| 226 | 240 |
| 227 void RtcEventLogImpl::StopLogging() { | 241 void RtcEventLogImpl::StopLogging() { |
| 228 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 242 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 229 RtcEventLogHelperThread::ControlMessage message; | 243 RtcEventLogHelperThread::ControlMessage message; |
| 230 message.message_type = RtcEventLogHelperThread::ControlMessage::STOP_FILE; | 244 message.message_type = RtcEventLogHelperThread::ControlMessage::STOP_FILE; |
| 231 message.stop_time = clock_->TimeInMicroseconds(); | 245 message.stop_time = clock_->TimeInMicroseconds(); |
| 232 while (!message_queue_.Insert(&message)) { | 246 while (!message_queue_.Insert(&message)) { |
| 233 // TODO(terelius): We would like to have a blocking Insert function in the | 247 // TODO(terelius): We would like to have a blocking Insert function in the |
| 234 // SwapQueue, but for the time being we will just clear any previous | 248 // SwapQueue, but for the time being we will just clear any previous |
| 235 // messages. | 249 // messages. |
| 236 // Since StopLogging waits for the thread, it is essential that we don't | 250 // Since StopLogging waits for the thread, it is essential that we don't |
| 237 // clear any STOP_FILE messages. To ensure that there is only one call at a | 251 // clear any STOP_FILE messages. To ensure that there is only one call at a |
| 238 // time, we require that all calls to StopLogging are made on the same | 252 // time, we require that all calls to StopLogging are made on the same |
| 239 // thread. | 253 // thread. |
| 240 LOG(LS_WARNING) << "Message queue full. Clearing queue to stop logging."; | 254 LOG(LS_ERROR) << "Message queue full. Clearing queue to stop logging."; |
| 241 message_queue_.Clear(); | 255 message_queue_.Clear(); |
| 242 } | 256 } |
| 257 LOG(LS_INFO) << "Stopping WebRTC event log."; | |
| 243 wake_up_.Set(); // Request the output thread to wake up. | 258 wake_up_.Set(); // Request the output thread to wake up. |
| 244 stopped_.Wait(rtc::Event::kForever); // Wait for the log to stop. | 259 stopped_.Wait(rtc::Event::kForever); // Wait for the log to stop. |
| 245 } | 260 } |
| 246 | 261 |
| 247 void RtcEventLogImpl::LogVideoReceiveStreamConfig( | 262 void RtcEventLogImpl::LogVideoReceiveStreamConfig( |
| 248 const VideoReceiveStream::Config& config) { | 263 const VideoReceiveStream::Config& config) { |
| 249 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 264 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
| 250 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 265 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 251 event->set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); | 266 event->set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); |
| 252 | 267 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 271 extension->set_name(e.name); | 286 extension->set_name(e.name); |
| 272 extension->set_id(e.id); | 287 extension->set_id(e.id); |
| 273 } | 288 } |
| 274 | 289 |
| 275 for (const auto& d : config.decoders) { | 290 for (const auto& d : config.decoders) { |
| 276 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); | 291 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); |
| 277 decoder->set_name(d.payload_name); | 292 decoder->set_name(d.payload_name); |
| 278 decoder->set_payload_type(d.payload_type); | 293 decoder->set_payload_type(d.payload_type); |
| 279 } | 294 } |
| 280 if (!event_queue_.Insert(&event)) { | 295 if (!event_queue_.Insert(&event)) { |
| 281 LOG(LS_WARNING) << "Config queue full. Not logging config event."; | 296 LOG(LS_ERROR) << "Config queue full. Not logging config event."; |
| 282 } | 297 } |
| 283 } | 298 } |
| 284 | 299 |
| 285 void RtcEventLogImpl::LogVideoSendStreamConfig( | 300 void RtcEventLogImpl::LogVideoSendStreamConfig( |
| 286 const VideoSendStream::Config& config) { | 301 const VideoSendStream::Config& config) { |
| 287 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 302 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
| 288 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 303 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 289 event->set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); | 304 event->set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); |
| 290 | 305 |
| 291 rtclog::VideoSendConfig* sender_config = event->mutable_video_sender_config(); | 306 rtclog::VideoSendConfig* sender_config = event->mutable_video_sender_config(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 303 | 318 |
| 304 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) { | 319 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) { |
| 305 sender_config->add_rtx_ssrcs(rtx_ssrc); | 320 sender_config->add_rtx_ssrcs(rtx_ssrc); |
| 306 } | 321 } |
| 307 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); | 322 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); |
| 308 | 323 |
| 309 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); | 324 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); |
| 310 encoder->set_name(config.encoder_settings.payload_name); | 325 encoder->set_name(config.encoder_settings.payload_name); |
| 311 encoder->set_payload_type(config.encoder_settings.payload_type); | 326 encoder->set_payload_type(config.encoder_settings.payload_type); |
| 312 if (!event_queue_.Insert(&event)) { | 327 if (!event_queue_.Insert(&event)) { |
| 313 LOG(LS_WARNING) << "Config queue full. Not logging config event."; | 328 LOG(LS_ERROR) << "Config queue full. Not logging config event."; |
| 314 } | 329 } |
| 315 } | 330 } |
| 316 | 331 |
| 317 void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, | 332 void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, |
| 318 MediaType media_type, | 333 MediaType media_type, |
| 319 const uint8_t* header, | 334 const uint8_t* header, |
| 320 size_t packet_length) { | 335 size_t packet_length) { |
| 321 // Read header length (in bytes) from packet data. | 336 // Read header length (in bytes) from packet data. |
| 322 if (packet_length < 12u) { | 337 if (packet_length < 12u) { |
| 323 return; // Don't read outside the packet. | 338 return; // Don't read outside the packet. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 335 } | 350 } |
| 336 | 351 |
| 337 std::unique_ptr<rtclog::Event> rtp_event(new rtclog::Event()); | 352 std::unique_ptr<rtclog::Event> rtp_event(new rtclog::Event()); |
| 338 rtp_event->set_timestamp_us(clock_->TimeInMicroseconds()); | 353 rtp_event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 339 rtp_event->set_type(rtclog::Event::RTP_EVENT); | 354 rtp_event->set_type(rtclog::Event::RTP_EVENT); |
| 340 rtp_event->mutable_rtp_packet()->set_incoming(direction == kIncomingPacket); | 355 rtp_event->mutable_rtp_packet()->set_incoming(direction == kIncomingPacket); |
| 341 rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type)); | 356 rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type)); |
| 342 rtp_event->mutable_rtp_packet()->set_packet_length(packet_length); | 357 rtp_event->mutable_rtp_packet()->set_packet_length(packet_length); |
| 343 rtp_event->mutable_rtp_packet()->set_header(header, header_length); | 358 rtp_event->mutable_rtp_packet()->set_header(header, header_length); |
| 344 if (!event_queue_.Insert(&rtp_event)) { | 359 if (!event_queue_.Insert(&rtp_event)) { |
| 345 LOG(LS_WARNING) << "RTP queue full. Not logging RTP packet."; | 360 LOG(LS_ERROR) << "RTP queue full. Not logging RTP packet."; |
| 346 } | 361 } |
| 347 } | 362 } |
| 348 | 363 |
| 349 void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction, | 364 void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction, |
| 350 MediaType media_type, | 365 MediaType media_type, |
| 351 const uint8_t* packet, | 366 const uint8_t* packet, |
| 352 size_t length) { | 367 size_t length) { |
| 353 std::unique_ptr<rtclog::Event> rtcp_event(new rtclog::Event()); | 368 std::unique_ptr<rtclog::Event> rtcp_event(new rtclog::Event()); |
| 354 rtcp_event->set_timestamp_us(clock_->TimeInMicroseconds()); | 369 rtcp_event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 355 rtcp_event->set_type(rtclog::Event::RTCP_EVENT); | 370 rtcp_event->set_type(rtclog::Event::RTCP_EVENT); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 default: | 410 default: |
| 396 // We don't log sender descriptions, application defined messages | 411 // We don't log sender descriptions, application defined messages |
| 397 // or message blocks of unknown type. | 412 // or message blocks of unknown type. |
| 398 break; | 413 break; |
| 399 } | 414 } |
| 400 | 415 |
| 401 block_begin += block_size; | 416 block_begin += block_size; |
| 402 } | 417 } |
| 403 rtcp_event->mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); | 418 rtcp_event->mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); |
| 404 if (!event_queue_.Insert(&rtcp_event)) { | 419 if (!event_queue_.Insert(&rtcp_event)) { |
| 405 LOG(LS_WARNING) << "RTCP queue full. Not logging RTCP packet."; | 420 LOG(LS_ERROR) << "RTCP queue full. Not logging RTCP packet."; |
| 406 } | 421 } |
| 407 } | 422 } |
| 408 | 423 |
| 409 void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) { | 424 void RtcEventLogImpl::LogAudioPlayout(uint32_t ssrc) { |
| 410 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 425 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
| 411 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 426 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 412 event->set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT); | 427 event->set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT); |
| 413 auto playout_event = event->mutable_audio_playout_event(); | 428 auto playout_event = event->mutable_audio_playout_event(); |
| 414 playout_event->set_local_ssrc(ssrc); | 429 playout_event->set_local_ssrc(ssrc); |
| 415 if (!event_queue_.Insert(&event)) { | 430 if (!event_queue_.Insert(&event)) { |
| 416 LOG(LS_WARNING) << "Playout queue full. Not logging ACM playout."; | 431 LOG(LS_ERROR) << "Playout queue full. Not logging ACM playout."; |
| 417 } | 432 } |
| 418 } | 433 } |
| 419 | 434 |
| 420 void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate, | 435 void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate, |
| 421 uint8_t fraction_loss, | 436 uint8_t fraction_loss, |
| 422 int32_t total_packets) { | 437 int32_t total_packets) { |
| 423 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); | 438 std::unique_ptr<rtclog::Event> event(new rtclog::Event()); |
| 424 event->set_timestamp_us(clock_->TimeInMicroseconds()); | 439 event->set_timestamp_us(clock_->TimeInMicroseconds()); |
| 425 event->set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT); | 440 event->set_type(rtclog::Event::BWE_PACKET_LOSS_EVENT); |
| 426 auto bwe_event = event->mutable_bwe_packet_loss_event(); | 441 auto bwe_event = event->mutable_bwe_packet_loss_event(); |
| 427 bwe_event->set_bitrate(bitrate); | 442 bwe_event->set_bitrate(bitrate); |
| 428 bwe_event->set_fraction_loss(fraction_loss); | 443 bwe_event->set_fraction_loss(fraction_loss); |
| 429 bwe_event->set_total_packets(total_packets); | 444 bwe_event->set_total_packets(total_packets); |
| 430 if (!event_queue_.Insert(&event)) { | 445 if (!event_queue_.Insert(&event)) { |
| 431 LOG(LS_WARNING) << "BWE loss queue full. Not logging BWE update."; | 446 LOG(LS_ERROR) << "BWE loss queue full. Not logging BWE update."; |
| 432 } | 447 } |
| 433 } | 448 } |
| 434 | 449 |
| 435 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, | 450 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, |
| 436 rtclog::EventStream* result) { | 451 rtclog::EventStream* result) { |
| 437 char tmp_buffer[1024]; | 452 char tmp_buffer[1024]; |
| 438 int bytes_read = 0; | 453 int bytes_read = 0; |
| 439 std::unique_ptr<FileWrapper> dump_file(FileWrapper::Create()); | 454 std::unique_ptr<FileWrapper> dump_file(FileWrapper::Create()); |
| 440 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { | 455 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { |
| 441 return false; | 456 return false; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 453 // RtcEventLog member functions. | 468 // RtcEventLog member functions. |
| 454 std::unique_ptr<RtcEventLog> RtcEventLog::Create(const Clock* clock) { | 469 std::unique_ptr<RtcEventLog> RtcEventLog::Create(const Clock* clock) { |
| 455 #ifdef ENABLE_RTC_EVENT_LOG | 470 #ifdef ENABLE_RTC_EVENT_LOG |
| 456 return std::unique_ptr<RtcEventLog>(new RtcEventLogImpl(clock)); | 471 return std::unique_ptr<RtcEventLog>(new RtcEventLogImpl(clock)); |
| 457 #else | 472 #else |
| 458 return std::unique_ptr<RtcEventLog>(new RtcEventLogNullImpl()); | 473 return std::unique_ptr<RtcEventLog>(new RtcEventLogNullImpl()); |
| 459 #endif // ENABLE_RTC_EVENT_LOG | 474 #endif // ENABLE_RTC_EVENT_LOG |
| 460 } | 475 } |
| 461 | 476 |
| 462 } // namespace webrtc | 477 } // namespace webrtc |
| OLD | NEW |