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 17 matching lines...) Expand all Loading... | |
| 28 #endif | 28 #endif |
| 29 #endif | 29 #endif |
| 30 | 30 |
| 31 namespace webrtc { | 31 namespace webrtc { |
| 32 | 32 |
| 33 #ifndef ENABLE_RTC_EVENT_LOG | 33 #ifndef ENABLE_RTC_EVENT_LOG |
| 34 | 34 |
| 35 // No-op implementation if flag is not set. | 35 // No-op implementation if flag is not set. |
| 36 class RtcEventLogImpl final : public RtcEventLog { | 36 class RtcEventLogImpl final : public RtcEventLog { |
| 37 public: | 37 public: |
| 38 void SetBufferDuration(int64_t recent_log_duration_us) override {} | |
| 38 void StartLogging(const std::string& file_name, int duration_ms) override {} | 39 void StartLogging(const std::string& file_name, int duration_ms) override {} |
| 39 void StopLogging(void) override {} | 40 void StopLogging(void) override {} |
| 40 void LogVideoReceiveStreamConfig( | 41 void LogVideoReceiveStreamConfig( |
| 41 const VideoReceiveStream::Config& config) override {} | 42 const VideoReceiveStream::Config& config) override {} |
| 42 void LogVideoSendStreamConfig( | 43 void LogVideoSendStreamConfig( |
| 43 const VideoSendStream::Config& config) override {} | 44 const VideoSendStream::Config& config) override {} |
| 44 void LogRtpHeader(bool incoming, | 45 void LogRtpHeader(bool incoming, |
| 45 MediaType media_type, | 46 MediaType media_type, |
| 46 const uint8_t* header, | 47 const uint8_t* header, |
| 47 size_t header_length, | 48 size_t header_length, |
| 48 size_t total_length) override {} | 49 size_t total_length) override {} |
| 49 void LogRtcpPacket(bool incoming, | 50 void LogRtcpPacket(bool incoming, |
| 50 MediaType media_type, | 51 MediaType media_type, |
| 51 const uint8_t* packet, | 52 const uint8_t* packet, |
| 52 size_t length) override {} | 53 size_t length) override {} |
| 53 void LogDebugEvent(DebugEvent event_type) override {} | 54 void LogDebugEvent(DebugEvent event_type) override {} |
| 54 }; | 55 }; |
| 55 | 56 |
| 56 #else // ENABLE_RTC_EVENT_LOG is defined | 57 #else // ENABLE_RTC_EVENT_LOG is defined |
| 57 | 58 |
| 58 class RtcEventLogImpl final : public RtcEventLog { | 59 class RtcEventLogImpl final : public RtcEventLog { |
| 59 public: | 60 public: |
| 60 RtcEventLogImpl(); | 61 RtcEventLogImpl(); |
| 61 | 62 |
| 63 void SetBufferDuration(int64_t recent_log_duration_us) override; | |
| 62 void StartLogging(const std::string& file_name, int duration_ms) override; | 64 void StartLogging(const std::string& file_name, int duration_ms) override; |
| 63 void StopLogging() override; | 65 void StopLogging() override; |
| 64 void LogVideoReceiveStreamConfig( | 66 void LogVideoReceiveStreamConfig( |
| 65 const VideoReceiveStream::Config& config) override; | 67 const VideoReceiveStream::Config& config) override; |
| 66 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override; | 68 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override; |
| 67 void LogRtpHeader(bool incoming, | 69 void LogRtpHeader(bool incoming, |
| 68 MediaType media_type, | 70 MediaType media_type, |
| 69 const uint8_t* header, | 71 const uint8_t* header, |
| 70 size_t header_length, | 72 size_t header_length, |
| 71 size_t total_length) override; | 73 size_t total_length) override; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 82 // list of recent log events otherwise. | 84 // list of recent log events otherwise. |
| 83 void HandleEvent(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); | 85 void HandleEvent(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); |
| 84 // Writes the event to the file. Note that this will destroy the state of the | 86 // Writes the event to the file. Note that this will destroy the state of the |
| 85 // input argument. | 87 // input argument. |
| 86 void StoreToFile(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); | 88 void StoreToFile(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); |
| 87 // Adds the event to the list of recent events, and removes any events that | 89 // Adds the event to the list of recent events, and removes any events that |
| 88 // are too old and no longer fall in the time window. | 90 // are too old and no longer fall in the time window. |
| 89 void AddRecentEvent(const rtclog::Event& event) | 91 void AddRecentEvent(const rtclog::Event& event) |
| 90 EXCLUSIVE_LOCKS_REQUIRED(crit_); | 92 EXCLUSIVE_LOCKS_REQUIRED(crit_); |
| 91 | 93 |
| 92 // Amount of time in microseconds to record log events, before starting the | |
| 93 // actual log. | |
| 94 const int recent_log_duration_us = 10000000; | |
| 95 | |
| 96 rtc::CriticalSection crit_; | 94 rtc::CriticalSection crit_; |
| 97 rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_); | 95 rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_); |
| 98 rtclog::EventStream stream_ GUARDED_BY(crit_); | 96 rtclog::EventStream stream_ GUARDED_BY(crit_); |
| 99 std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_); | 97 std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_); |
| 98 std::vector<rtclog::Event> config_events_ GUARDED_BY(crit_); | |
| 99 | |
| 100 // Microseconds to record log events, before starting the actual log. | |
| 101 int64_t recent_log_duration_us_ GUARDED_BY(crit_); | |
| 100 bool currently_logging_ GUARDED_BY(crit_); | 102 bool currently_logging_ GUARDED_BY(crit_); |
| 101 int64_t start_time_us_ GUARDED_BY(crit_); | 103 int64_t start_time_us_ GUARDED_BY(crit_); |
| 102 int64_t duration_us_ GUARDED_BY(crit_); | 104 int64_t duration_us_ GUARDED_BY(crit_); |
| 103 const Clock* const clock_; | 105 const Clock* const clock_; |
| 104 }; | 106 }; |
| 105 | 107 |
| 106 namespace { | 108 namespace { |
| 107 // The functions in this namespace convert enums from the runtime format | 109 // The functions in this namespace convert enums from the runtime format |
| 108 // that the rest of the WebRtc project can use, to the corresponding | 110 // that the rest of the WebRtc project can use, to the corresponding |
| 109 // serialized enum which is defined by the protobuf. | 111 // serialized enum which is defined by the protobuf. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 RTC_NOTREACHED(); | 154 RTC_NOTREACHED(); |
| 153 return rtclog::ANY; | 155 return rtclog::ANY; |
| 154 } | 156 } |
| 155 | 157 |
| 156 } // namespace | 158 } // namespace |
| 157 | 159 |
| 158 // RtcEventLogImpl member functions. | 160 // RtcEventLogImpl member functions. |
| 159 RtcEventLogImpl::RtcEventLogImpl() | 161 RtcEventLogImpl::RtcEventLogImpl() |
| 160 : file_(FileWrapper::Create()), | 162 : file_(FileWrapper::Create()), |
| 161 stream_(), | 163 stream_(), |
| 164 recent_log_duration_us_(10000000), | |
| 162 currently_logging_(false), | 165 currently_logging_(false), |
| 163 start_time_us_(0), | 166 start_time_us_(0), |
| 164 duration_us_(0), | 167 duration_us_(0), |
| 165 clock_(Clock::GetRealTimeClock()) { | 168 clock_(Clock::GetRealTimeClock()) { |
| 166 } | 169 } |
| 167 | 170 |
| 171 void RtcEventLogImpl::SetBufferDuration(int64_t recent_log_duration_us) { | |
| 172 rtc::CritScope lock(&crit_); | |
| 173 recent_log_duration_us_ = recent_log_duration_us; | |
|
ivoc
2015/08/25 08:03:21
Shouldn't there be some sort of purging of the buf
terelius
2015/08/25 16:41:44
The old events are purged whenever we add a new ev
ivoc
2015/08/26 08:15:28
Acknowledged.
| |
| 174 } | |
| 175 | |
| 168 void RtcEventLogImpl::StartLogging(const std::string& file_name, | 176 void RtcEventLogImpl::StartLogging(const std::string& file_name, |
| 169 int duration_ms) { | 177 int duration_ms) { |
| 170 rtc::CritScope lock(&crit_); | 178 rtc::CritScope lock(&crit_); |
| 171 if (currently_logging_) { | 179 if (currently_logging_) { |
| 172 StopLoggingLocked(); | 180 StopLoggingLocked(); |
| 173 } | 181 } |
| 174 if (file_->OpenFile(file_name.c_str(), false) != 0) { | 182 if (file_->OpenFile(file_name.c_str(), false) != 0) { |
| 175 return; | 183 return; |
| 176 } | 184 } |
| 177 currently_logging_ = true; | 185 currently_logging_ = true; |
| 178 start_time_us_ = clock_->TimeInMicroseconds(); | 186 start_time_us_ = clock_->TimeInMicroseconds(); |
| 179 duration_us_ = static_cast<int64_t>(duration_ms) * 1000; | 187 duration_us_ = static_cast<int64_t>(duration_ms) * 1000; |
| 180 // Write all the recent events to the log file, ignoring any old events. | 188 // Write all old configuration events to the log file. |
| 189 for (auto& event : config_events_) { | |
| 190 StoreToFile(&event); | |
| 191 } | |
| 192 // Write all recent configuration events to the log file, and | |
| 193 // write all other recent events to the log file, ignoring any old events. | |
| 181 for (auto& event : recent_log_events_) { | 194 for (auto& event : recent_log_events_) { |
| 182 if (event.timestamp_us() >= start_time_us_ - recent_log_duration_us) { | 195 if (event.type() == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT || |
| 196 event.type() == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT || | |
| 197 event.type() == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT || | |
| 198 event.type() == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT) { | |
| 199 StoreToFile(&event); | |
| 200 config_events_.push_back(event); | |
| 201 } else if (event.timestamp_us() >= | |
| 202 start_time_us_ - recent_log_duration_us_) { | |
| 183 StoreToFile(&event); | 203 StoreToFile(&event); |
| 184 } | 204 } |
| 185 } | 205 } |
| 186 recent_log_events_.clear(); | 206 recent_log_events_.clear(); |
| 187 // Write a LOG_START event to the file. | 207 // Write a LOG_START event to the file. |
| 188 rtclog::Event start_event; | 208 rtclog::Event start_event; |
| 189 start_event.set_timestamp_us(start_time_us_); | 209 start_event.set_timestamp_us(start_time_us_); |
| 190 start_event.set_type(rtclog::Event::DEBUG_EVENT); | 210 start_event.set_type(rtclog::Event::DEBUG_EVENT); |
| 191 auto debug_event = start_event.mutable_debug_event(); | 211 auto debug_event = start_event.mutable_debug_event(); |
| 192 debug_event->set_type(ConvertDebugEvent(DebugEvent::kLogStart)); | 212 debug_event->set_type(ConvertDebugEvent(DebugEvent::kLogStart)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 receiver_config->add_header_extensions(); | 250 receiver_config->add_header_extensions(); |
| 231 extension->set_name(e.name); | 251 extension->set_name(e.name); |
| 232 extension->set_id(e.id); | 252 extension->set_id(e.id); |
| 233 } | 253 } |
| 234 | 254 |
| 235 for (const auto& d : config.decoders) { | 255 for (const auto& d : config.decoders) { |
| 236 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); | 256 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); |
| 237 decoder->set_name(d.payload_name); | 257 decoder->set_name(d.payload_name); |
| 238 decoder->set_payload_type(d.payload_type); | 258 decoder->set_payload_type(d.payload_type); |
| 239 } | 259 } |
| 240 // TODO(terelius): We should use a separate event queue for config events. | 260 // TODO(terelius): We should use a separate event queue for config events. |
|
ivoc
2015/08/25 08:03:21
I guess this TODO can be removed in this CL.
terelius
2015/08/25 16:41:44
Yeah, that was kind of the point of the CL. :)
| |
| 241 // The current approach of storing the configuration together with the | 261 // The current approach of storing the configuration together with the |
| 242 // RTP events causes the configuration information to be removed 10s | 262 // RTP events causes the configuration information to be removed 10s |
| 243 // after the ReceiveStream is created. | 263 // after the ReceiveStream is created. |
| 244 HandleEvent(&event); | 264 HandleEvent(&event); |
| 245 } | 265 } |
| 246 | 266 |
| 247 void RtcEventLogImpl::LogVideoSendStreamConfig( | 267 void RtcEventLogImpl::LogVideoSendStreamConfig( |
| 248 const VideoSendStream::Config& config) { | 268 const VideoSendStream::Config& config) { |
| 249 rtc::CritScope lock(&crit_); | 269 rtc::CritScope lock(&crit_); |
| 250 | 270 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 270 sender_config->add_rtx_ssrcs(rtx_ssrc); | 290 sender_config->add_rtx_ssrcs(rtx_ssrc); |
| 271 } | 291 } |
| 272 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); | 292 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); |
| 273 | 293 |
| 274 sender_config->set_c_name(config.rtp.c_name); | 294 sender_config->set_c_name(config.rtp.c_name); |
| 275 | 295 |
| 276 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); | 296 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); |
| 277 encoder->set_name(config.encoder_settings.payload_name); | 297 encoder->set_name(config.encoder_settings.payload_name); |
| 278 encoder->set_payload_type(config.encoder_settings.payload_type); | 298 encoder->set_payload_type(config.encoder_settings.payload_type); |
| 279 | 299 |
| 280 // TODO(terelius): We should use a separate event queue for config events. | 300 // TODO(terelius): We should use a separate event queue for config events. |
|
ivoc
2015/08/25 08:03:21
This one as well.
terelius
2015/08/25 16:41:44
Done.
| |
| 281 // The current approach of storing the configuration together with the | 301 // The current approach of storing the configuration together with the |
| 282 // RTP events causes the configuration information to be removed 10s | 302 // RTP events causes the configuration information to be removed 10s |
| 283 // after the ReceiveStream is created. | 303 // after the ReceiveStream is created. |
| 284 HandleEvent(&event); | 304 HandleEvent(&event); |
| 285 } | 305 } |
| 286 | 306 |
| 287 // TODO(terelius): It is more convenient and less error prone to parse the | 307 // TODO(terelius): It is more convenient and less error prone to parse the |
| 288 // header length from the packet instead of relying on the caller to provide it. | 308 // header length from the packet instead of relying on the caller to provide it. |
| 289 void RtcEventLogImpl::LogRtpHeader(bool incoming, | 309 void RtcEventLogImpl::LogRtpHeader(bool incoming, |
| 290 MediaType media_type, | 310 MediaType media_type, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 // TODO(terelius): Doesn't this create a new EventStream per event? | 389 // TODO(terelius): Doesn't this create a new EventStream per event? |
| 370 // Is this guaranteed to work e.g. in future versions of protobuf? | 390 // Is this guaranteed to work e.g. in future versions of protobuf? |
| 371 std::string dump_buffer; | 391 std::string dump_buffer; |
| 372 stream_.SerializeToString(&dump_buffer); | 392 stream_.SerializeToString(&dump_buffer); |
| 373 file_->Write(dump_buffer.data(), dump_buffer.size()); | 393 file_->Write(dump_buffer.data(), dump_buffer.size()); |
| 374 } | 394 } |
| 375 | 395 |
| 376 void RtcEventLogImpl::AddRecentEvent(const rtclog::Event& event) { | 396 void RtcEventLogImpl::AddRecentEvent(const rtclog::Event& event) { |
| 377 recent_log_events_.push_back(event); | 397 recent_log_events_.push_back(event); |
| 378 while (recent_log_events_.front().timestamp_us() < | 398 while (recent_log_events_.front().timestamp_us() < |
| 379 event.timestamp_us() - recent_log_duration_us) { | 399 event.timestamp_us() - recent_log_duration_us_) { |
| 400 rtclog::Event_EventType event_type = recent_log_events_.front().type(); | |
| 401 if (event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT || | |
| 402 event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT || | |
| 403 event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT || | |
| 404 event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT) { | |
| 405 config_events_.push_back(recent_log_events_.front()); | |
|
ivoc
2015/08/25 08:03:21
I wonder if we should be checking if any of the co
terelius
2015/08/25 16:41:44
This is a good point.
I don't think it is possibl
ivoc
2015/08/26 08:15:28
I think a check here would solve this problem. Eve
ivoc
2015/09/25 15:30:23
Could you respond to this? I still think it would
terelius
2015/10/15 13:28:21
So what you are proposing is checking whether ther
ivoc
2015/10/15 15:52:06
Okay, let's stick to the simple solution for now.
| |
| 406 } | |
| 380 recent_log_events_.pop_front(); | 407 recent_log_events_.pop_front(); |
| 381 } | 408 } |
| 382 } | 409 } |
| 383 | 410 |
| 384 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, | 411 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, |
| 385 rtclog::EventStream* result) { | 412 rtclog::EventStream* result) { |
| 386 char tmp_buffer[1024]; | 413 char tmp_buffer[1024]; |
| 387 int bytes_read = 0; | 414 int bytes_read = 0; |
| 388 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create()); | 415 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create()); |
| 389 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { | 416 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { |
| 390 return false; | 417 return false; |
| 391 } | 418 } |
| 392 std::string dump_buffer; | 419 std::string dump_buffer; |
| 393 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) { | 420 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) { |
| 394 dump_buffer.append(tmp_buffer, bytes_read); | 421 dump_buffer.append(tmp_buffer, bytes_read); |
| 395 } | 422 } |
| 396 dump_file->CloseFile(); | 423 dump_file->CloseFile(); |
| 397 return result->ParseFromString(dump_buffer); | 424 return result->ParseFromString(dump_buffer); |
| 398 } | 425 } |
| 399 | 426 |
| 400 #endif // ENABLE_RTC_EVENT_LOG | 427 #endif // ENABLE_RTC_EVENT_LOG |
| 401 | 428 |
| 402 // RtcEventLog member functions. | 429 // RtcEventLog member functions. |
| 403 rtc::scoped_ptr<RtcEventLog> RtcEventLog::Create() { | 430 rtc::scoped_ptr<RtcEventLog> RtcEventLog::Create() { |
| 404 return rtc::scoped_ptr<RtcEventLog>(new RtcEventLogImpl()); | 431 return rtc::scoped_ptr<RtcEventLog>(new RtcEventLogImpl()); |
| 405 } | 432 } |
| 433 | |
| 406 } // namespace webrtc | 434 } // namespace webrtc |
| OLD | NEW |