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

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/acm_dump.cc

Issue 1209563002: Added support for keeping a buffer of the previous X seconds, to add to (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed Karl's review comments. Created 5 years, 5 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/modules/audio_coding/main/acm2/acm_dump.h" 11 #include "webrtc/modules/audio_coding/main/acm2/acm_dump.h"
12 12
13 #include <sstream> 13 #include <deque>
14 14
15 #include "webrtc/base/checks.h" 15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/thread_annotations.h" 16 #include "webrtc/base/thread_annotations.h"
17 #include "webrtc/system_wrappers/interface/clock.h" 17 #include "webrtc/system_wrappers/interface/clock.h"
18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/interface/file_wrapper.h" 19 #include "webrtc/system_wrappers/interface/file_wrapper.h"
20 20
21 // Files generated at build-time by the protobuf compiler. 21 // Files generated at build-time by the protobuf compiler.
22 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD 22 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
23 #include "external/webrtc/webrtc/modules/audio_coding/dump.pb.h" 23 #include "external/webrtc/webrtc/modules/audio_coding/dump.pb.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 void Clear() EXCLUSIVE_LOCKS_REQUIRED(crit_); 60 void Clear() EXCLUSIVE_LOCKS_REQUIRED(crit_);
61 // Returns true if the logging is currently active. 61 // Returns true if the logging is currently active.
62 bool CurrentlyLogging() const EXCLUSIVE_LOCKS_REQUIRED(crit_) { 62 bool CurrentlyLogging() const EXCLUSIVE_LOCKS_REQUIRED(crit_) {
63 return active_ && 63 return active_ &&
64 (clock_->TimeInMicroseconds() <= start_time_us_ + duration_us_); 64 (clock_->TimeInMicroseconds() <= start_time_us_ + duration_us_);
65 } 65 }
66 // This function is identical to LogDebugEvent, but requires holding the lock. 66 // This function is identical to LogDebugEvent, but requires holding the lock.
67 void LogDebugEventLocked(DebugEvent event_type, 67 void LogDebugEventLocked(DebugEvent event_type,
68 const std::string& event_message) 68 const std::string& event_message)
69 EXCLUSIVE_LOCKS_REQUIRED(crit_); 69 EXCLUSIVE_LOCKS_REQUIRED(crit_);
70 // Writes the event to the file. Note that this will destroy the state of the
71 // input argument.
72 void StoreToFile(ACMDumpEvent* event) EXCLUSIVE_LOCKS_REQUIRED(crit_);
73 // Adds the event to the list of recent events, and removes any events that
74 // are too old and no longer fall in the time window.
75 void AddRecentEvent(const ACMDumpEvent& event)
76 EXCLUSIVE_LOCKS_REQUIRED(crit_);
77
78 // Amount of time in us to record log events, before starting the actual log.
hlundin-webrtc 2015/06/25 13:20:56 Write microseconds instead of us in comments. Alth
ivoc 2015/06/25 13:55:22 Good point.
79 const int recent_log_duration_us = 10000000;
70 80
71 rtc::scoped_ptr<webrtc::CriticalSectionWrapper> crit_; 81 rtc::scoped_ptr<webrtc::CriticalSectionWrapper> crit_;
72 rtc::scoped_ptr<webrtc::FileWrapper> file_ GUARDED_BY(crit_); 82 rtc::scoped_ptr<webrtc::FileWrapper> file_ GUARDED_BY(crit_);
73 rtc::scoped_ptr<ACMDumpEventStream> stream_ GUARDED_BY(crit_); 83 rtc::scoped_ptr<ACMDumpEventStream> stream_ GUARDED_BY(crit_);
84 std::deque<ACMDumpEvent> recent_log_events_ GUARDED_BY(crit_);
74 bool active_ GUARDED_BY(crit_); 85 bool active_ GUARDED_BY(crit_);
75 int64_t start_time_us_ GUARDED_BY(crit_); 86 int64_t start_time_us_ GUARDED_BY(crit_);
76 int64_t duration_us_ GUARDED_BY(crit_); 87 int64_t duration_us_ GUARDED_BY(crit_);
77 const webrtc::Clock* clock_ GUARDED_BY(crit_); 88 const webrtc::Clock* clock_ GUARDED_BY(crit_);
78 }; 89 };
79 90
80 namespace { 91 namespace {
81 92
82 // Convert from AcmDump's debug event enum (runtime format) to the corresponding 93 // Convert from AcmDump's debug event enum (runtime format) to the corresponding
83 // protobuf enum (serialized format). 94 // protobuf enum (serialized format).
(...skipping 21 matching lines...) Expand all
105 duration_us_(0), 116 duration_us_(0),
106 clock_(webrtc::Clock::GetRealTimeClock()) { 117 clock_(webrtc::Clock::GetRealTimeClock()) {
107 } 118 }
108 119
109 void AcmDumpImpl::StartLogging(const std::string& file_name, int duration_ms) { 120 void AcmDumpImpl::StartLogging(const std::string& file_name, int duration_ms) {
110 CriticalSectionScoped lock(crit_.get()); 121 CriticalSectionScoped lock(crit_.get());
111 Clear(); 122 Clear();
112 if (file_->OpenFile(file_name.c_str(), false) != 0) { 123 if (file_->OpenFile(file_name.c_str(), false) != 0) {
113 return; 124 return;
114 } 125 }
115 // Add a single object to the stream that is reused at every log event. 126 // Add start event to the recent event list, and remove any old events from
hlundin-webrtc 2015/06/25 13:20:56 The comment is slightly confusing. I first thought
ivoc 2015/06/25 13:55:23 What I meant to say is that this call to LogDebugE
116 stream_->add_stream(); 127 // the list.
128 LogDebugEventLocked(DebugEvent::kLogStart, "");
117 active_ = true; 129 active_ = true;
118 start_time_us_ = clock_->TimeInMicroseconds(); 130 start_time_us_ = clock_->TimeInMicroseconds();
119 duration_us_ = static_cast<int64_t>(duration_ms) * 1000; 131 duration_us_ = static_cast<int64_t>(duration_ms) * 1000;
120 // Log the start event. 132 // Write all the recent events to the log file.
121 std::stringstream log_msg; 133 for (auto&& event : recent_log_events_) {
122 log_msg << "Initial timestamp: " << start_time_us_; 134 StoreToFile(&event);
123 LogDebugEventLocked(DebugEvent::kLogStart, log_msg.str()); 135 }
136 recent_log_events_.clear();
124 } 137 }
125 138
126 void AcmDumpImpl::LogRtpPacket(bool incoming, 139 void AcmDumpImpl::LogRtpPacket(bool incoming,
127 const uint8_t* packet, 140 const uint8_t* packet,
128 size_t length) { 141 size_t length) {
129 CriticalSectionScoped lock(crit_.get()); 142 CriticalSectionScoped lock(crit_.get());
130 if (!CurrentlyLogging()) { 143 ACMDumpEvent rtp_event;
144 rtp_event.clear_debug_event();
145 const int64_t timestamp = clock_->TimeInMicroseconds();
146 rtp_event.set_timestamp_us(timestamp);
147 rtp_event.set_type(webrtc::ACMDumpEvent::RTP_EVENT);
148 rtp_event.mutable_packet()->set_direction(
149 incoming ? ACMDumpRTPPacket::INCOMING : ACMDumpRTPPacket::OUTGOING);
150 rtp_event.mutable_packet()->set_rtp_data(packet, length);
151 if (CurrentlyLogging()) {
152 StoreToFile(&rtp_event);
153 } else {
131 StopIfNecessary(); 154 StopIfNecessary();
132 return; 155 AddRecentEvent(rtp_event);
133 } 156 }
134 // Reuse the same object at every log event.
135 auto rtp_event = stream_->mutable_stream(0);
136 rtp_event->clear_debug_event();
137 const int64_t timestamp = clock_->TimeInMicroseconds() - start_time_us_;
138 rtp_event->set_timestamp_us(timestamp);
139 rtp_event->set_type(webrtc::ACMDumpEvent::RTP_EVENT);
140 rtp_event->mutable_packet()->set_direction(
141 incoming ? ACMDumpRTPPacket::INCOMING : ACMDumpRTPPacket::OUTGOING);
142 rtp_event->mutable_packet()->set_rtp_data(packet, length);
143 std::string dump_buffer;
144 stream_->SerializeToString(&dump_buffer);
145 file_->Write(dump_buffer.data(), dump_buffer.size());
146 file_->Flush();
147 } 157 }
148 158
149 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type, 159 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type,
150 const std::string& event_message) { 160 const std::string& event_message) {
151 CriticalSectionScoped lock(crit_.get()); 161 CriticalSectionScoped lock(crit_.get());
152 LogDebugEventLocked(event_type, event_message); 162 LogDebugEventLocked(event_type, event_message);
153 } 163 }
154 164
155 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type) { 165 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type) {
156 CriticalSectionScoped lock(crit_.get()); 166 CriticalSectionScoped lock(crit_.get());
(...skipping 11 matching lines...) Expand all
168 void AcmDumpImpl::Clear() { 178 void AcmDumpImpl::Clear() {
169 if (active_ || file_->Open()) { 179 if (active_ || file_->Open()) {
170 file_->CloseFile(); 180 file_->CloseFile();
171 } 181 }
172 active_ = false; 182 active_ = false;
173 stream_->Clear(); 183 stream_->Clear();
174 } 184 }
175 185
176 void AcmDumpImpl::LogDebugEventLocked(DebugEvent event_type, 186 void AcmDumpImpl::LogDebugEventLocked(DebugEvent event_type,
177 const std::string& event_message) { 187 const std::string& event_message) {
178 if (!CurrentlyLogging()) { 188 ACMDumpEvent event;
179 StopIfNecessary(); 189 int64_t timestamp = clock_->TimeInMicroseconds();
180 return; 190 event.set_timestamp_us(timestamp);
181 } 191 event.set_type(webrtc::ACMDumpEvent::DEBUG_EVENT);
182 192 event.clear_packet();
183 // Reuse the same object at every log event. 193 auto debug_event = event.mutable_debug_event();
184 auto event = stream_->mutable_stream(0);
185 int64_t timestamp = clock_->TimeInMicroseconds() - start_time_us_;
186 event->set_timestamp_us(timestamp);
187 event->set_type(webrtc::ACMDumpEvent::DEBUG_EVENT);
188 event->clear_packet();
189 auto debug_event = event->mutable_debug_event();
190 debug_event->set_type(convertDebugEvent(event_type)); 194 debug_event->set_type(convertDebugEvent(event_type));
191 debug_event->set_message(event_message); 195 debug_event->set_message(event_message);
196 if (CurrentlyLogging()) {
197 StoreToFile(&event);
198 } else {
199 StopIfNecessary();
200 AddRecentEvent(event);
201 }
202 }
203
204 void AcmDumpImpl::StoreToFile(ACMDumpEvent* event) {
205 // Reuse the same object at every log event.
206 if (stream_->stream_size() < 1) {
207 stream_->add_stream();
208 }
209 stream_->mutable_stream(0)->Swap(event);
210
192 std::string dump_buffer; 211 std::string dump_buffer;
193 stream_->SerializeToString(&dump_buffer); 212 stream_->SerializeToString(&dump_buffer);
194 file_->Write(dump_buffer.data(), dump_buffer.size()); 213 file_->Write(dump_buffer.data(), dump_buffer.size());
195 } 214 }
196 215
216 void AcmDumpImpl::AddRecentEvent(const ACMDumpEvent& event) {
217 recent_log_events_.push_back(event);
218 while (recent_log_events_.front().timestamp_us() <
219 event.timestamp_us() - recent_log_duration_us) {
220 recent_log_events_.pop_front();
221 }
222 }
223
197 #endif // RTC_AUDIOCODING_DEBUG_DUMP 224 #endif // RTC_AUDIOCODING_DEBUG_DUMP
198 225
199 // AcmDump member functions. 226 // AcmDump member functions.
200 rtc::scoped_ptr<AcmDump> AcmDump::Create() { 227 rtc::scoped_ptr<AcmDump> AcmDump::Create() {
201 return rtc::scoped_ptr<AcmDump>(new AcmDumpImpl()); 228 return rtc::scoped_ptr<AcmDump>(new AcmDumpImpl());
202 } 229 }
203 230
204 bool AcmDump::ParseAcmDump(const std::string& file_name, 231 bool AcmDump::ParseAcmDump(const std::string& file_name,
205 ACMDumpEventStream* result) { 232 ACMDumpEventStream* result) {
206 char tmp_buffer[1024]; 233 char tmp_buffer[1024];
207 int bytes_read = 0; 234 int bytes_read = 0;
208 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create()); 235 rtc::scoped_ptr<FileWrapper> dump_file(FileWrapper::Create());
209 if (dump_file->OpenFile(file_name.c_str(), true) != 0) { 236 if (dump_file->OpenFile(file_name.c_str(), true) != 0) {
210 return false; 237 return false;
211 } 238 }
212 std::string dump_buffer; 239 std::string dump_buffer;
213 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) { 240 while ((bytes_read = dump_file->Read(tmp_buffer, sizeof(tmp_buffer))) > 0) {
214 dump_buffer.append(tmp_buffer, bytes_read); 241 dump_buffer.append(tmp_buffer, bytes_read);
215 } 242 }
216 dump_file->CloseFile(); 243 dump_file->CloseFile();
217 return result->ParseFromString(dump_buffer); 244 return result->ParseFromString(dump_buffer);
218 } 245 }
219 246
220 } // namespace webrtc 247 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698