Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(523)

Side by Side Diff: webrtc/video/rtc_event_log.cc

Issue 1303713002: Keep config events in RtcEventLog even if they are old. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Lock before changing buffer duration Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698