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

Side by Side Diff: webrtc/call/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: Rebase again Created 5 years, 2 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
11 #include "webrtc/call/rtc_event_log.h" 11 #include "webrtc/call/rtc_event_log.h"
12 12
13 #include <deque> 13 #include <deque>
14 #include <vector>
14 15
15 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
16 #include "webrtc/base/criticalsection.h" 17 #include "webrtc/base/criticalsection.h"
17 #include "webrtc/base/thread_annotations.h" 18 #include "webrtc/base/thread_annotations.h"
18 #include "webrtc/call.h" 19 #include "webrtc/call.h"
19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 20 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
20 #include "webrtc/system_wrappers/interface/clock.h" 21 #include "webrtc/system_wrappers/interface/clock.h"
21 #include "webrtc/system_wrappers/interface/file_wrapper.h" 22 #include "webrtc/system_wrappers/interface/file_wrapper.h"
22 23
23 #ifdef ENABLE_RTC_EVENT_LOG 24 #ifdef ENABLE_RTC_EVENT_LOG
24 // Files generated at build-time by the protobuf compiler. 25 // Files generated at build-time by the protobuf compiler.
25 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD 26 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
26 #include "external/webrtc/webrtc/call/rtc_event_log.pb.h" 27 #include "external/webrtc/webrtc/call/rtc_event_log.pb.h"
27 #else 28 #else
28 #include "webrtc/call/rtc_event_log.pb.h" 29 #include "webrtc/call/rtc_event_log.pb.h"
29 #endif 30 #endif
30 #endif 31 #endif
31 32
32 namespace webrtc { 33 namespace webrtc {
33 34
34 #ifndef ENABLE_RTC_EVENT_LOG 35 #ifndef ENABLE_RTC_EVENT_LOG
35 36
36 // No-op implementation if flag is not set. 37 // No-op implementation if flag is not set.
37 class RtcEventLogImpl final : public RtcEventLog { 38 class RtcEventLogImpl final : public RtcEventLog {
38 public: 39 public:
40 void SetBufferDuration(int64_t buffer_duration_us) override {}
39 void StartLogging(const std::string& file_name, int duration_ms) override {} 41 void StartLogging(const std::string& file_name, int duration_ms) override {}
40 bool StartLogging(rtc::PlatformFile log_file) override { return false; } 42 bool StartLogging(rtc::PlatformFile log_file) override { return false; }
41 void StopLogging(void) override {} 43 void StopLogging(void) override {}
42 void LogVideoReceiveStreamConfig( 44 void LogVideoReceiveStreamConfig(
43 const VideoReceiveStream::Config& config) override {} 45 const VideoReceiveStream::Config& config) override {}
44 void LogVideoSendStreamConfig( 46 void LogVideoSendStreamConfig(
45 const VideoSendStream::Config& config) override {} 47 const VideoSendStream::Config& config) override {}
46 void LogRtpHeader(bool incoming, 48 void LogRtpHeader(bool incoming,
47 MediaType media_type, 49 MediaType media_type,
48 const uint8_t* header, 50 const uint8_t* header,
49 size_t packet_length) override {} 51 size_t packet_length) override {}
50 void LogRtcpPacket(bool incoming, 52 void LogRtcpPacket(bool incoming,
51 MediaType media_type, 53 MediaType media_type,
52 const uint8_t* packet, 54 const uint8_t* packet,
53 size_t length) override {} 55 size_t length) override {}
54 void LogAudioPlayout(uint32_t ssrc) override {} 56 void LogAudioPlayout(uint32_t ssrc) override {}
55 }; 57 };
56 58
57 #else // ENABLE_RTC_EVENT_LOG is defined 59 #else // ENABLE_RTC_EVENT_LOG is defined
58 60
59 class RtcEventLogImpl final : public RtcEventLog { 61 class RtcEventLogImpl final : public RtcEventLog {
60 public: 62 public:
63 RtcEventLogImpl();
64
65 void SetBufferDuration(int64_t buffer_duration_us) override;
61 void StartLogging(const std::string& file_name, int duration_ms) override; 66 void StartLogging(const std::string& file_name, int duration_ms) override;
62 bool StartLogging(rtc::PlatformFile log_file) override; 67 bool StartLogging(rtc::PlatformFile log_file) override;
63 void StopLogging() override; 68 void StopLogging() override;
64 void LogVideoReceiveStreamConfig( 69 void LogVideoReceiveStreamConfig(
65 const VideoReceiveStream::Config& config) override; 70 const VideoReceiveStream::Config& config) override;
66 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override; 71 void LogVideoSendStreamConfig(const VideoSendStream::Config& config) override;
67 void LogRtpHeader(bool incoming, 72 void LogRtpHeader(bool incoming,
68 MediaType media_type, 73 MediaType media_type,
69 const uint8_t* header, 74 const uint8_t* header,
70 size_t packet_length) override; 75 size_t packet_length) override;
(...skipping 13 matching lines...) Expand all
84 // list of recent log events otherwise. 89 // list of recent log events otherwise.
85 void HandleEvent(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); 90 void HandleEvent(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_);
86 // Writes the event to the file. Note that this will destroy the state of the 91 // Writes the event to the file. Note that this will destroy the state of the
87 // input argument. 92 // input argument.
88 void StoreToFile(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_); 93 void StoreToFile(rtclog::Event* event) EXCLUSIVE_LOCKS_REQUIRED(crit_);
89 // Adds the event to the list of recent events, and removes any events that 94 // Adds the event to the list of recent events, and removes any events that
90 // are too old and no longer fall in the time window. 95 // are too old and no longer fall in the time window.
91 void AddRecentEvent(const rtclog::Event& event) 96 void AddRecentEvent(const rtclog::Event& event)
92 EXCLUSIVE_LOCKS_REQUIRED(crit_); 97 EXCLUSIVE_LOCKS_REQUIRED(crit_);
93 98
94 // Amount of time in microseconds to record log events, before starting the
95 // actual log.
96 const int recent_log_duration_us = 10000000;
97
98 rtc::CriticalSection crit_; 99 rtc::CriticalSection crit_;
99 rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_) = 100 rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_) =
100 rtc::scoped_ptr<FileWrapper>(FileWrapper::Create()); 101 rtc::scoped_ptr<FileWrapper>(FileWrapper::Create());
101 rtc::PlatformFile platform_file_ GUARDED_BY(crit_) = 102 rtc::PlatformFile platform_file_ GUARDED_BY(crit_) =
102 rtc::kInvalidPlatformFileValue; 103 rtc::kInvalidPlatformFileValue;
103 rtclog::EventStream stream_ GUARDED_BY(crit_); 104 rtclog::EventStream stream_ GUARDED_BY(crit_);
104 std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_); 105 std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_);
105 bool currently_logging_ GUARDED_BY(crit_) = false; 106 std::vector<rtclog::Event> config_events_ GUARDED_BY(crit_);
106 int64_t start_time_us_ GUARDED_BY(crit_) = 0; 107
107 int64_t duration_us_ GUARDED_BY(crit_) = 0; 108 // Microseconds to record log events, before starting the actual log.
108 const Clock* const clock_ = Clock::GetRealTimeClock(); 109 int64_t buffer_duration_us_ GUARDED_BY(crit_);
110 bool currently_logging_ GUARDED_BY(crit_);
111 int64_t start_time_us_ GUARDED_BY(crit_);
112 int64_t duration_us_ GUARDED_BY(crit_);
113 const Clock* const clock_;
109 }; 114 };
110 115
111 namespace { 116 namespace {
112 // The functions in this namespace convert enums from the runtime format 117 // The functions in this namespace convert enums from the runtime format
113 // that the rest of the WebRtc project can use, to the corresponding 118 // that the rest of the WebRtc project can use, to the corresponding
114 // serialized enum which is defined by the protobuf. 119 // serialized enum which is defined by the protobuf.
115 120
116 // Do not add default return values to the conversion functions in this 121 // Do not add default return values to the conversion functions in this
117 // unnamed namespace. The intention is to make the compiler warn if anyone 122 // unnamed namespace. The intention is to make the compiler warn if anyone
118 // adds unhandled new events/modes/etc. 123 // adds unhandled new events/modes/etc.
(...skipping 22 matching lines...) Expand all
141 return rtclog::MediaType::VIDEO; 146 return rtclog::MediaType::VIDEO;
142 case MediaType::DATA: 147 case MediaType::DATA:
143 return rtclog::MediaType::DATA; 148 return rtclog::MediaType::DATA;
144 } 149 }
145 RTC_NOTREACHED(); 150 RTC_NOTREACHED();
146 return rtclog::ANY; 151 return rtclog::ANY;
147 } 152 }
148 153
149 } // namespace 154 } // namespace
150 155
156 namespace {
157 bool IsConfigEvent(const rtclog::Event& event) {
158 rtclog::Event_EventType event_type = event.type();
159 return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT ||
160 event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT ||
161 event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT ||
162 event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT;
163 }
164 } // namespace
165
151 // RtcEventLogImpl member functions. 166 // RtcEventLogImpl member functions.
167 RtcEventLogImpl::RtcEventLogImpl()
168 : file_(FileWrapper::Create()),
169 stream_(),
170 buffer_duration_us_(10000000),
171 currently_logging_(false),
172 start_time_us_(0),
173 duration_us_(0),
174 clock_(Clock::GetRealTimeClock()) {
175 }
176
177 void RtcEventLogImpl::SetBufferDuration(int64_t buffer_duration_us) {
178 rtc::CritScope lock(&crit_);
179 buffer_duration_us_ = buffer_duration_us;
180 }
152 181
153 void RtcEventLogImpl::StartLogging(const std::string& file_name, 182 void RtcEventLogImpl::StartLogging(const std::string& file_name,
154 int duration_ms) { 183 int duration_ms) {
155 rtc::CritScope lock(&crit_); 184 rtc::CritScope lock(&crit_);
156 if (currently_logging_) { 185 if (currently_logging_) {
157 StopLoggingLocked(); 186 StopLoggingLocked();
158 } 187 }
159 if (file_->OpenFile(file_name.c_str(), false) != 0) { 188 if (file_->OpenFile(file_name.c_str(), false) != 0) {
160 return; 189 return;
161 } 190 }
(...skipping 23 matching lines...) Expand all
185 platform_file_ = log_file; 214 platform_file_ = log_file;
186 // Set the start time and duration to keep logging for 10 minutes. 215 // Set the start time and duration to keep logging for 10 minutes.
187 start_time_us_ = clock_->TimeInMicroseconds(); 216 start_time_us_ = clock_->TimeInMicroseconds();
188 duration_us_ = 10 * 60 * 1000000; 217 duration_us_ = 10 * 60 * 1000000;
189 StartLoggingLocked(); 218 StartLoggingLocked();
190 return true; 219 return true;
191 } 220 }
192 221
193 void RtcEventLogImpl::StartLoggingLocked() { 222 void RtcEventLogImpl::StartLoggingLocked() {
194 currently_logging_ = true; 223 currently_logging_ = true;
195 // Write all the recent events to the log file, ignoring any old events. 224
225 // Write all old configuration events to the log file.
226 for (auto& event : config_events_) {
227 StoreToFile(&event);
228 }
229 // Write all recent configuration events to the log file, and
230 // write all other recent events to the log file, ignoring any old events.
196 for (auto& event : recent_log_events_) { 231 for (auto& event : recent_log_events_) {
197 if (event.timestamp_us() >= start_time_us_ - recent_log_duration_us) { 232 if (IsConfigEvent(event)) {
233 StoreToFile(&event);
234 config_events_.push_back(event);
235 } else if (event.timestamp_us() >= start_time_us_ - buffer_duration_us_) {
198 StoreToFile(&event); 236 StoreToFile(&event);
199 } 237 }
200 } 238 }
201 recent_log_events_.clear(); 239 recent_log_events_.clear();
202 // Write a LOG_START event to the file. 240 // Write a LOG_START event to the file.
203 rtclog::Event start_event; 241 rtclog::Event start_event;
204 start_event.set_timestamp_us(start_time_us_); 242 start_event.set_timestamp_us(start_time_us_);
205 start_event.set_type(rtclog::Event::LOG_START); 243 start_event.set_type(rtclog::Event::LOG_START);
206 StoreToFile(&start_event); 244 StoreToFile(&start_event);
207 } 245 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 receiver_config->add_header_extensions(); 281 receiver_config->add_header_extensions();
244 extension->set_name(e.name); 282 extension->set_name(e.name);
245 extension->set_id(e.id); 283 extension->set_id(e.id);
246 } 284 }
247 285
248 for (const auto& d : config.decoders) { 286 for (const auto& d : config.decoders) {
249 rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); 287 rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
250 decoder->set_name(d.payload_name); 288 decoder->set_name(d.payload_name);
251 decoder->set_payload_type(d.payload_type); 289 decoder->set_payload_type(d.payload_type);
252 } 290 }
253 // TODO(terelius): We should use a separate event queue for config events.
254 // The current approach of storing the configuration together with the
255 // RTP events causes the configuration information to be removed 10s
256 // after the ReceiveStream is created.
257 HandleEvent(&event); 291 HandleEvent(&event);
258 } 292 }
259 293
260 void RtcEventLogImpl::LogVideoSendStreamConfig( 294 void RtcEventLogImpl::LogVideoSendStreamConfig(
261 const VideoSendStream::Config& config) { 295 const VideoSendStream::Config& config) {
262 rtc::CritScope lock(&crit_); 296 rtc::CritScope lock(&crit_);
263 297
264 rtclog::Event event; 298 rtclog::Event event;
265 const int64_t timestamp = clock_->TimeInMicroseconds(); 299 const int64_t timestamp = clock_->TimeInMicroseconds();
266 event.set_timestamp_us(timestamp); 300 event.set_timestamp_us(timestamp);
(...skipping 15 matching lines...) Expand all
282 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) { 316 for (const auto& rtx_ssrc : config.rtp.rtx.ssrcs) {
283 sender_config->add_rtx_ssrcs(rtx_ssrc); 317 sender_config->add_rtx_ssrcs(rtx_ssrc);
284 } 318 }
285 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); 319 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type);
286 320
287 sender_config->set_c_name(config.rtp.c_name); 321 sender_config->set_c_name(config.rtp.c_name);
288 322
289 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); 323 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
290 encoder->set_name(config.encoder_settings.payload_name); 324 encoder->set_name(config.encoder_settings.payload_name);
291 encoder->set_payload_type(config.encoder_settings.payload_type); 325 encoder->set_payload_type(config.encoder_settings.payload_type);
292
293 // TODO(terelius): We should use a separate event queue for config events.
294 // The current approach of storing the configuration together with the
295 // RTP events causes the configuration information to be removed 10s
296 // after the ReceiveStream is created.
297 HandleEvent(&event); 326 HandleEvent(&event);
298 } 327 }
299 328
300 void RtcEventLogImpl::LogRtpHeader(bool incoming, 329 void RtcEventLogImpl::LogRtpHeader(bool incoming,
301 MediaType media_type, 330 MediaType media_type,
302 const uint8_t* header, 331 const uint8_t* header,
303 size_t packet_length) { 332 size_t packet_length) {
304 // Read header length (in bytes) from packet data. 333 // Read header length (in bytes) from packet data.
305 if (packet_length < 12u) { 334 if (packet_length < 12u) {
306 return; // Don't read outside the packet. 335 return; // Don't read outside the packet.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 // TODO(terelius): Doesn't this create a new EventStream per event? 426 // TODO(terelius): Doesn't this create a new EventStream per event?
398 // Is this guaranteed to work e.g. in future versions of protobuf? 427 // Is this guaranteed to work e.g. in future versions of protobuf?
399 std::string dump_buffer; 428 std::string dump_buffer;
400 stream_.SerializeToString(&dump_buffer); 429 stream_.SerializeToString(&dump_buffer);
401 file_->Write(dump_buffer.data(), dump_buffer.size()); 430 file_->Write(dump_buffer.data(), dump_buffer.size());
402 } 431 }
403 432
404 void RtcEventLogImpl::AddRecentEvent(const rtclog::Event& event) { 433 void RtcEventLogImpl::AddRecentEvent(const rtclog::Event& event) {
405 recent_log_events_.push_back(event); 434 recent_log_events_.push_back(event);
406 while (recent_log_events_.front().timestamp_us() < 435 while (recent_log_events_.front().timestamp_us() <
407 event.timestamp_us() - recent_log_duration_us) { 436 event.timestamp_us() - buffer_duration_us_) {
437 if (IsConfigEvent(recent_log_events_.front())) {
438 config_events_.push_back(recent_log_events_.front());
439 }
408 recent_log_events_.pop_front(); 440 recent_log_events_.pop_front();
409 } 441 }
410 } 442 }
411 443
412 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name, 444 bool RtcEventLog::ParseRtcEventLog(const std::string& file_name,
413 rtclog::EventStream* result) { 445 rtclog::EventStream* result) {
414 char tmp_buffer[1024]; 446 char tmp_buffer[1024];
415 int bytes_read = 0; 447 int bytes_read = 0;
416 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create()); 448 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create());
417 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { 449 if (dump_file->OpenFile(file_name.c_str(), true) != 0) {
418 return false; 450 return false;
419 } 451 }
420 std::string dump_buffer; 452 std::string dump_buffer;
421 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) { 453 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) {
422 dump_buffer.append(tmp_buffer, bytes_read); 454 dump_buffer.append(tmp_buffer, bytes_read);
423 } 455 }
424 dump_file->CloseFile(); 456 dump_file->CloseFile();
425 return result->ParseFromString(dump_buffer); 457 return result->ParseFromString(dump_buffer);
426 } 458 }
427 459
428 #endif // ENABLE_RTC_EVENT_LOG 460 #endif // ENABLE_RTC_EVENT_LOG
429 461
430 // RtcEventLog member functions. 462 // RtcEventLog member functions.
431 rtc::scoped_ptr<RtcEventLog> RtcEventLog::Create() { 463 rtc::scoped_ptr<RtcEventLog> RtcEventLog::Create() {
432 return rtc::scoped_ptr<RtcEventLog>(new RtcEventLogImpl()); 464 return rtc::scoped_ptr<RtcEventLog>(new RtcEventLogImpl());
433 } 465 }
466
434 } // namespace webrtc 467 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698