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 |
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 <deque> | 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 | |
21 #ifdef RTC_AUDIOCODING_DEBUG_DUMP | 22 #ifdef RTC_AUDIOCODING_DEBUG_DUMP |
22 // Files generated at build-time by the protobuf compiler. | 23 // Files generated at build-time by the protobuf compiler. |
23 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD | 24 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD |
24 #include "external/webrtc/webrtc/modules/audio_coding/dump.pb.h" | 25 #include "external/webrtc/webrtc/modules/audio_coding/dump.pb.h" |
25 #else | 26 #else |
26 #include "webrtc/audio_coding/dump.pb.h" | 27 #include "webrtc/audio_coding/dump.pb.h" |
27 #endif | 28 #endif |
28 #endif | 29 #endif |
29 | 30 |
30 namespace webrtc { | 31 namespace webrtc { |
31 | 32 |
32 // Noop implementation if flag is not set | 33 // Noop implementation if flag is not set. |
33 #ifndef RTC_AUDIOCODING_DEBUG_DUMP | 34 #ifndef RTC_AUDIOCODING_DEBUG_DUMP |
34 class AcmDumpImpl final : public AcmDump { | 35 class AcmDumpImpl final : public AcmDump { |
35 public: | 36 public: |
36 void StartLogging(const std::string& file_name, int duration_ms) override{}; | 37 void StartLogging(const std::string& file_name, int duration_ms) override{}; |
37 void LogRtpPacket(bool incoming, | 38 void LogVideoReceiveStreamConfig( |
38 const uint8_t* packet, | 39 const webrtc::VideoReceiveStream::Config& config) override{}; |
39 size_t length) override{}; | 40 void LogVideoSendStreamConfig( |
41 const webrtc::VideoSendStream::Config& config) override{}; | |
42 void LogRtpHeader(bool incoming, | |
43 MediaType media_type, | |
44 const uint8_t* header, | |
45 size_t header_length, | |
46 size_t total_length) override{}; | |
47 void LogRtcpPacket(bool incoming, | |
48 MediaType media_type, | |
49 const uint8_t* packet, | |
50 size_t length) override{}; | |
40 void LogDebugEvent(DebugEvent event_type, | 51 void LogDebugEvent(DebugEvent event_type, |
41 const std::string& event_message) override{}; | 52 const std::string& event_message) override{}; |
42 void LogDebugEvent(DebugEvent event_type) override{}; | 53 void LogDebugEvent(DebugEvent event_type) override{}; |
43 }; | 54 }; |
44 #else | 55 #else |
45 | 56 |
46 class AcmDumpImpl final : public AcmDump { | 57 class AcmDumpImpl final : public AcmDump { |
47 public: | 58 public: |
48 AcmDumpImpl(); | 59 AcmDumpImpl(); |
49 | 60 |
50 void StartLogging(const std::string& file_name, int duration_ms) override; | 61 void StartLogging(const std::string& file_name, int duration_ms) override; |
51 void LogRtpPacket(bool incoming, | 62 void LogVideoReceiveStreamConfig( |
52 const uint8_t* packet, | 63 const webrtc::VideoReceiveStream::Config& config) override; |
53 size_t length) override; | 64 void LogVideoSendStreamConfig( |
65 const webrtc::VideoSendStream::Config& config) override; | |
66 void LogRtpHeader(bool incoming, | |
67 MediaType media_type, | |
68 const uint8_t* header, | |
69 size_t header_length, | |
70 size_t total_length) override; | |
71 void LogRtcpPacket(bool incoming, | |
72 MediaType media_type, | |
73 const uint8_t* packet, | |
74 size_t length) override; | |
54 void LogDebugEvent(DebugEvent event_type, | 75 void LogDebugEvent(DebugEvent event_type, |
55 const std::string& event_message) override; | 76 const std::string& event_message) override; |
56 void LogDebugEvent(DebugEvent event_type) override; | 77 void LogDebugEvent(DebugEvent event_type) override; |
57 | 78 |
58 private: | 79 private: |
59 // This function is identical to LogDebugEvent, but requires holding the lock. | 80 // This function is identical to LogDebugEvent, but requires holding the lock. |
60 void LogDebugEventLocked(DebugEvent event_type, | 81 void LogDebugEventLocked(DebugEvent event_type, |
61 const std::string& event_message) | 82 const std::string& event_message) |
62 EXCLUSIVE_LOCKS_REQUIRED(crit_); | 83 EXCLUSIVE_LOCKS_REQUIRED(crit_); |
63 // Stops logging and clears the stored data and buffers. | 84 // Stops logging and clears the stored data and buffers. |
(...skipping 49 matching lines...) Loading... | |
113 currently_logging_(false), | 134 currently_logging_(false), |
114 start_time_us_(0), | 135 start_time_us_(0), |
115 duration_us_(0), | 136 duration_us_(0), |
116 clock_(webrtc::Clock::GetRealTimeClock()) { | 137 clock_(webrtc::Clock::GetRealTimeClock()) { |
117 } | 138 } |
118 | 139 |
119 void AcmDumpImpl::StartLogging(const std::string& file_name, int duration_ms) { | 140 void AcmDumpImpl::StartLogging(const std::string& file_name, int duration_ms) { |
120 CriticalSectionScoped lock(crit_.get()); | 141 CriticalSectionScoped lock(crit_.get()); |
121 Clear(); | 142 Clear(); |
122 if (file_->OpenFile(file_name.c_str(), false) != 0) { | 143 if (file_->OpenFile(file_name.c_str(), false) != 0) { |
144 // printf("Cannot open file %s\n", file_name.c_str()); | |
ivoc
2015/07/14 12:13:13
Should be removed.
terelius
2015/07/16 12:47:02
Done.
| |
123 return; | 145 return; |
124 } | 146 } |
147 | |
125 // Add LOG_START event to the recent event list. This call will also remove | 148 // Add LOG_START event to the recent event list. This call will also remove |
126 // any events that are too old from the recent event list. | 149 // any events that are too old from the recent event list. |
127 LogDebugEventLocked(DebugEvent::kLogStart, ""); | 150 LogDebugEventLocked(DebugEvent::kLogStart, ""); |
128 currently_logging_ = true; | 151 currently_logging_ = true; |
129 start_time_us_ = clock_->TimeInMicroseconds(); | 152 start_time_us_ = clock_->TimeInMicroseconds(); |
130 duration_us_ = static_cast<int64_t>(duration_ms) * 1000; | 153 duration_us_ = static_cast<int64_t>(duration_ms) * 1000; |
131 // Write all the recent events to the log file. | 154 // Write all the recent events to the log file. |
155 // TODO(terelius): Rvalue references are unapproved. Do we need it? | |
ivoc
2015/07/14 12:13:13
I agree that it's not necessary. It should be auto
terelius
2015/07/16 12:47:02
Done.
| |
132 for (auto&& event : recent_log_events_) { | 156 for (auto&& event : recent_log_events_) { |
133 StoreToFile(&event); | 157 StoreToFile(&event); |
134 } | 158 } |
135 recent_log_events_.clear(); | 159 recent_log_events_.clear(); |
136 } | 160 } |
137 | 161 |
138 void AcmDumpImpl::LogRtpPacket(bool incoming, | 162 void AcmDumpImpl::LogVideoReceiveStreamConfig( |
139 const uint8_t* packet, | 163 const webrtc::VideoReceiveStream::Config& config) { |
140 size_t length) { | 164 CriticalSectionScoped lock(crit_.get()); |
165 | |
166 ACMDumpEvent event; | |
167 const int64_t timestamp = clock_->TimeInMicroseconds(); | |
168 event.set_timestamp_us(timestamp); | |
169 event.set_type(webrtc::ACMDumpEvent::RECEIVER_CONFIG_EVENT); | |
170 | |
171 ACMDumpVideoReceiveConfig* receiver_config = event.mutable_receiver_config(); | |
172 receiver_config->set_remote_ssrc(config.rtp.remote_ssrc); | |
173 receiver_config->set_local_ssrc(config.rtp.local_ssrc); | |
174 | |
175 switch (config.rtp.rtcp_mode) { | |
ivoc
2015/07/14 12:13:13
I think it would be clearer to refactor this into
terelius
2015/07/16 12:47:02
Done.
| |
176 case newapi::kRtcpCompound: | |
177 receiver_config->set_rtcp_mode(ACMDumpVideoReceiveConfig::RTCP_COMPOUND); | |
178 break; | |
179 case newapi::kRtcpReducedSize: | |
180 receiver_config->set_rtcp_mode( | |
181 ACMDumpVideoReceiveConfig::RTCP_REDUCEDSIZE); | |
182 break; | |
183 // Compiler should warn if anyone adds unhandled new modes. | |
stefan-webrtc
2015/07/14 13:28:56
No need for this comment I think.
terelius
2015/07/16 12:47:02
I'll put a general warning/explanation of why ther
| |
184 } | |
185 receiver_config->set_receiver_reference_time_report( | |
186 config.rtp.rtcp_xr.receiver_reference_time_report); | |
187 receiver_config->set_remb(config.rtp.remb); | |
188 | |
189 for (const auto& r : config.rtp.rtx) { | |
ivoc
2015/07/14 12:13:13
I'm not a fan of single-letter variable names (in
terelius
2015/07/16 12:47:02
Done.
| |
190 RtxMap* translation = receiver_config->add_rtx_map(); | |
191 translation->set_payload_type(r.first); | |
192 translation->mutable_config()->set_rtx_ssrc(r.second.ssrc); | |
193 translation->mutable_config()->set_rtx_payload_type(r.second.payload_type); | |
194 } | |
195 | |
196 for (const auto& e : config.rtp.extensions) { | |
ivoc
2015/07/14 12:13:13
e should be renamed to something more descriptive
terelius
2015/07/16 12:47:02
I'll change this, but I'll explain why I think the
| |
197 RtpHeaderExtension* extension = receiver_config->add_header_extensions(); | |
198 extension->set_name(e.name); | |
199 extension->set_id(e.id); | |
200 } | |
201 | |
202 for (const auto& d : config.decoders) { | |
ivoc
2015/07/14 12:13:13
Same for d.
terelius
2015/07/16 12:47:02
Done.
| |
203 DecoderConfig* decoder = receiver_config->add_decoders(); | |
204 decoder->set_name(d.payload_name); | |
205 decoder->set_payload_type(d.payload_type); | |
206 } | |
207 // TODO(terelius): We should use a separate event stream for config events. | |
208 // The current approach of storing the configuration together with the | |
209 // RTP events causes the configuration information to be removed 10s | |
210 // after the ReceiveStream is created. | |
ivoc
2015/07/14 12:13:13
I disagree. We can store this ACMDumpEvent as a me
terelius
2015/07/16 12:47:02
Acknowledged. I'll leave the comment as a reminder
| |
211 HandleEvent(&event); | |
212 } | |
213 | |
214 void AcmDumpImpl::LogVideoSendStreamConfig( | |
215 const webrtc::VideoSendStream::Config& config) { | |
216 CriticalSectionScoped lock(crit_.get()); | |
217 | |
218 ACMDumpEvent event; | |
219 const int64_t timestamp = clock_->TimeInMicroseconds(); | |
220 event.set_timestamp_us(timestamp); | |
221 event.set_type(webrtc::ACMDumpEvent::SENDER_CONFIG_EVENT); | |
222 | |
223 ACMDumpVideoSendConfig* sender_config = event.mutable_sender_config(); | |
224 | |
225 for (const auto& s : config.rtp.ssrcs) { | |
ivoc
2015/07/14 12:13:13
s should be more descriptive.
terelius
2015/07/16 12:47:02
Done.
| |
226 sender_config->add_ssrcs(s); | |
227 } | |
228 | |
229 for (const auto& e : config.rtp.extensions) { | |
ivoc
2015/07/14 12:13:13
Same here.
terelius
2015/07/16 12:47:02
Done.
| |
230 RtpHeaderExtension* extension = sender_config->add_header_extensions(); | |
231 extension->set_name(e.name); | |
232 extension->set_id(e.id); | |
233 } | |
234 | |
235 for (const auto& r : config.rtp.rtx.ssrcs) { | |
ivoc
2015/07/14 12:13:13
And here.
terelius
2015/07/16 12:47:02
Done.
| |
236 sender_config->add_rtx_ssrcs(r); | |
237 } | |
238 sender_config->set_rtx_payload_type(config.rtp.rtx.payload_type); | |
239 | |
240 sender_config->set_c_name(config.rtp.c_name); | |
241 | |
242 EncoderConfig* encoder = sender_config->mutable_encoder(); | |
243 encoder->set_name(config.encoder_settings.payload_name); | |
244 encoder->set_payload_type(config.encoder_settings.payload_type); | |
245 | |
246 // TODO(terelius): We should use a separate event stream for config events. | |
247 // The current approach of storing the configuration together with the | |
248 // RTP events causes the configuration information to be removed 10s | |
249 // after the ReceiveStream is created. | |
ivoc
2015/07/14 12:13:13
See my comment above.
terelius
2015/07/16 12:47:02
Acknowledged. I'll leave the comment as a reminder
| |
250 HandleEvent(&event); | |
251 } | |
252 | |
253 void AcmDumpImpl::LogRtpHeader(bool incoming, | |
254 MediaType media_type, | |
255 const uint8_t* header, | |
256 size_t header_length, | |
257 size_t total_length) { | |
141 CriticalSectionScoped lock(crit_.get()); | 258 CriticalSectionScoped lock(crit_.get()); |
142 ACMDumpEvent rtp_event; | 259 ACMDumpEvent rtp_event; |
143 const int64_t timestamp = clock_->TimeInMicroseconds(); | 260 const int64_t timestamp = clock_->TimeInMicroseconds(); |
144 rtp_event.set_timestamp_us(timestamp); | 261 rtp_event.set_timestamp_us(timestamp); |
145 rtp_event.set_type(webrtc::ACMDumpEvent::RTP_EVENT); | 262 rtp_event.set_type(webrtc::ACMDumpEvent::RTP_EVENT); |
146 rtp_event.mutable_packet()->set_direction( | 263 rtp_event.mutable_rtp_packet()->set_direction( |
147 incoming ? ACMDumpRTPPacket::INCOMING : ACMDumpRTPPacket::OUTGOING); | 264 incoming ? ACMDumpRtpPacket::INCOMING : ACMDumpRtpPacket::OUTGOING); |
148 rtp_event.mutable_packet()->set_rtp_data(packet, length); | 265 if (media_type == MediaType::VIDEO) |
ivoc
2015/07/14 12:13:13
I think we should make another small function to c
stefan-webrtc
2015/07/14 13:28:55
And I would prefer that function to use a switch i
terelius
2015/07/16 12:47:02
Done.
| |
266 rtp_event.mutable_rtp_packet()->set_type(ACMDumpRtpPacket::VIDEO); | |
267 else if (media_type == MediaType::AUDIO) | |
268 rtp_event.mutable_rtp_packet()->set_type(ACMDumpRtpPacket::AUDIO); | |
269 else | |
270 rtp_event.mutable_rtp_packet()->set_type(ACMDumpRtpPacket::UNKNOWN_TYPE); | |
271 rtp_event.mutable_rtp_packet()->set_packet_length(total_length); | |
272 rtp_event.mutable_rtp_packet()->set_header(header, header_length); | |
149 HandleEvent(&rtp_event); | 273 HandleEvent(&rtp_event); |
150 } | 274 } |
151 | 275 |
276 void AcmDumpImpl::LogRtcpPacket(bool incoming, | |
277 MediaType media_type, | |
278 const uint8_t* packet, | |
279 size_t length) { | |
280 CriticalSectionScoped lock(crit_.get()); | |
281 ACMDumpEvent rtcp_event; | |
282 const int64_t timestamp = clock_->TimeInMicroseconds(); | |
283 rtcp_event.set_timestamp_us(timestamp); | |
284 rtcp_event.set_type(webrtc::ACMDumpEvent::RTCP_EVENT); | |
285 rtcp_event.mutable_rtcp_packet()->set_direction( | |
ivoc
2015/07/14 12:13:13
We can reuse the conversion function here.
terelius
2015/07/16 12:47:02
We can't reuse it unless we change the protobuf.
A
ivoc
2015/07/17 12:14:28
Right, I misread.
| |
286 incoming ? ACMDumpRtcpPacket::INCOMING : ACMDumpRtcpPacket::OUTGOING); | |
287 if (media_type == MediaType::VIDEO) | |
288 rtcp_event.mutable_rtcp_packet()->set_type(ACMDumpRtcpPacket::VIDEO); | |
289 else if (media_type == MediaType::AUDIO) | |
290 rtcp_event.mutable_rtcp_packet()->set_type(ACMDumpRtcpPacket::AUDIO); | |
291 else | |
292 rtcp_event.mutable_rtcp_packet()->set_type(ACMDumpRtcpPacket::UNKNOWN_TYPE); | |
293 rtcp_event.mutable_rtcp_packet()->set_data(packet, length); | |
294 HandleEvent(&rtcp_event); | |
295 } | |
296 | |
152 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type, | 297 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type, |
153 const std::string& event_message) { | 298 const std::string& event_message) { |
154 CriticalSectionScoped lock(crit_.get()); | 299 CriticalSectionScoped lock(crit_.get()); |
155 LogDebugEventLocked(event_type, event_message); | 300 LogDebugEventLocked(event_type, event_message); |
156 } | 301 } |
157 | 302 |
158 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type) { | 303 void AcmDumpImpl::LogDebugEvent(DebugEvent event_type) { |
159 CriticalSectionScoped lock(crit_.get()); | 304 CriticalSectionScoped lock(crit_.get()); |
160 LogDebugEventLocked(event_type, ""); | 305 LogDebugEventLocked(event_type, ""); |
161 } | 306 } |
(...skipping 69 matching lines...) Loading... | |
231 return result->ParseFromString(dump_buffer); | 376 return result->ParseFromString(dump_buffer); |
232 } | 377 } |
233 | 378 |
234 #endif // RTC_AUDIOCODING_DEBUG_DUMP | 379 #endif // RTC_AUDIOCODING_DEBUG_DUMP |
235 | 380 |
236 // AcmDump member functions. | 381 // AcmDump member functions. |
237 rtc::scoped_ptr<AcmDump> AcmDump::Create() { | 382 rtc::scoped_ptr<AcmDump> AcmDump::Create() { |
238 return rtc::scoped_ptr<AcmDump>(new AcmDumpImpl()); | 383 return rtc::scoped_ptr<AcmDump>(new AcmDumpImpl()); |
239 } | 384 } |
240 } // namespace webrtc | 385 } // namespace webrtc |
OLD | NEW |