OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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/rtp_rtcp/source/rtp_sender_audio.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <memory> | 15 #include <memory> |
16 #include <utility> | 16 #include <utility> |
17 | 17 |
18 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
19 #include "webrtc/base/timeutils.h" | 19 #include "webrtc/base/timeutils.h" |
20 #include "webrtc/base/trace_event.h" | 20 #include "webrtc/base/trace_event.h" |
21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
23 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | 23 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
24 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" | 24 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
25 | 25 |
26 namespace webrtc { | 26 namespace webrtc { |
27 | 27 |
28 static const int kDtmfFrequencyHz = 8000; | |
29 | |
30 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) | 28 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) |
31 : clock_(clock), | 29 : clock_(clock), |
32 rtp_sender_(rtp_sender), | 30 rtp_sender_(rtp_sender) {} |
33 packet_size_samples_(160), | |
34 dtmf_event_is_on_(false), | |
35 dtmf_event_first_packet_sent_(false), | |
36 dtmf_payload_type_(-1), | |
37 dtmf_timestamp_(0), | |
38 dtmf_key_(0), | |
39 dtmf_length_samples_(0), | |
40 dtmf_level_(0), | |
41 dtmf_time_last_sent_(0), | |
42 dtmf_timestamp_last_sent_(0), | |
43 inband_vad_active_(false), | |
44 cngnb_payload_type_(-1), | |
45 cngwb_payload_type_(-1), | |
46 cngswb_payload_type_(-1), | |
47 cngfb_payload_type_(-1), | |
48 last_payload_type_(-1), | |
49 audio_level_dbov_(0) {} | |
50 | 31 |
51 RTPSenderAudio::~RTPSenderAudio() {} | 32 RTPSenderAudio::~RTPSenderAudio() {} |
52 | 33 |
53 // set audio packet size, used to determine when it's time to send a DTMF packet | 34 // set audio packet size, used to determine when it's time to send a DTMF packet |
54 // in silence (CNG) | 35 // in silence (CNG) |
55 int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packet_size_samples) { | 36 int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packet_size_samples) { |
56 rtc::CritScope cs(&send_audio_critsect_); | 37 rtc::CritScope cs(&send_audio_critsect_); |
57 packet_size_samples_ = packet_size_samples; | 38 packet_size_samples_ = packet_size_samples; |
58 return 0; | 39 return 0; |
59 } | 40 } |
(...skipping 22 matching lines...) Expand all Loading... |
82 cngfb_payload_type_ = payload_type; | 63 cngfb_payload_type_ = payload_type; |
83 break; | 64 break; |
84 default: | 65 default: |
85 return -1; | 66 return -1; |
86 } | 67 } |
87 } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) { | 68 } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) { |
88 rtc::CritScope cs(&send_audio_critsect_); | 69 rtc::CritScope cs(&send_audio_critsect_); |
89 // Don't add it to the list | 70 // Don't add it to the list |
90 // we dont want to allow send with a DTMF payloadtype | 71 // we dont want to allow send with a DTMF payloadtype |
91 dtmf_payload_type_ = payload_type; | 72 dtmf_payload_type_ = payload_type; |
| 73 dtmf_payload_freq_ = frequency; |
92 return 0; | 74 return 0; |
93 // The default timestamp rate is 8000 Hz, but other rates may be defined. | |
94 } | 75 } |
95 *payload = new RtpUtility::Payload; | 76 *payload = new RtpUtility::Payload; |
96 (*payload)->typeSpecific.Audio.frequency = frequency; | 77 (*payload)->typeSpecific.Audio.frequency = frequency; |
97 (*payload)->typeSpecific.Audio.channels = channels; | 78 (*payload)->typeSpecific.Audio.channels = channels; |
98 (*payload)->typeSpecific.Audio.rate = rate; | 79 (*payload)->typeSpecific.Audio.rate = rate; |
99 (*payload)->audio = true; | 80 (*payload)->audio = true; |
100 (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0'; | 81 (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0'; |
101 strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); | 82 strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); |
102 return 0; | 83 return 0; |
103 } | 84 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 125 } |
145 return marker_bit; | 126 return marker_bit; |
146 } | 127 } |
147 | 128 |
148 bool RTPSenderAudio::SendAudio(FrameType frame_type, | 129 bool RTPSenderAudio::SendAudio(FrameType frame_type, |
149 int8_t payload_type, | 130 int8_t payload_type, |
150 uint32_t rtp_timestamp, | 131 uint32_t rtp_timestamp, |
151 const uint8_t* payload_data, | 132 const uint8_t* payload_data, |
152 size_t payload_size, | 133 size_t payload_size, |
153 const RTPFragmentationHeader* fragmentation) { | 134 const RTPFragmentationHeader* fragmentation) { |
154 // TODO(pwestin) Breakup function in smaller functions. | 135 uint8_t audio_level_dbov = 0; |
155 uint16_t dtmf_length_ms = 0; | 136 uint16_t packet_size_samples = 0; |
156 uint8_t key = 0; | 137 uint32_t dtmf_payload_freq = 0; |
157 uint8_t audio_level_dbov; | |
158 int8_t dtmf_payload_type; | |
159 uint16_t packet_size_samples; | |
160 { | 138 { |
161 rtc::CritScope cs(&send_audio_critsect_); | 139 rtc::CritScope cs(&send_audio_critsect_); |
162 audio_level_dbov = audio_level_dbov_; | 140 audio_level_dbov = audio_level_dbov_; |
163 dtmf_payload_type = dtmf_payload_type_; | |
164 packet_size_samples = packet_size_samples_; | 141 packet_size_samples = packet_size_samples_; |
| 142 dtmf_payload_freq = dtmf_payload_freq_; |
165 } | 143 } |
166 | 144 |
167 // Check if we have pending DTMFs to send | 145 // Check if we have pending DTMFs to send |
168 if (!dtmf_event_is_on_ && dtmf_queue_.PendingDTMF()) { | 146 if (!dtmf_event_is_on_ && dtmf_queue_.PendingDtmf()) { |
169 int64_t delaySinceLastDTMF = | 147 if ((clock_->TimeInMilliseconds() - dtmf_time_last_sent_) > 50) { |
170 clock_->TimeInMilliseconds() - dtmf_time_last_sent_; | |
171 | |
172 if (delaySinceLastDTMF > 100) { | |
173 // New tone to play | 148 // New tone to play |
174 dtmf_timestamp_ = rtp_timestamp; | 149 dtmf_timestamp_ = rtp_timestamp; |
175 if (dtmf_queue_.NextDTMF(&key, &dtmf_length_ms, &dtmf_level_) >= 0) { | 150 if (dtmf_queue_.NextDtmf(&dtmf_current_event_)) { |
176 dtmf_event_first_packet_sent_ = false; | 151 dtmf_event_first_packet_sent_ = false; |
177 dtmf_key_ = key; | 152 dtmf_length_samples_ = |
178 dtmf_length_samples_ = (kDtmfFrequencyHz / 1000) * dtmf_length_ms; | 153 dtmf_current_event_.duration_ms * (dtmf_payload_freq / 1000); |
179 dtmf_event_is_on_ = true; | 154 dtmf_event_is_on_ = true; |
180 } | 155 } |
181 } | 156 } |
182 } | 157 } |
183 | 158 |
184 // A source MAY send events and coded audio packets for the same time | 159 // A source MAY send events and coded audio packets for the same time |
185 // but we don't support it | 160 // but we don't support it |
186 if (dtmf_event_is_on_) { | 161 if (dtmf_event_is_on_) { |
187 if (frame_type == kEmptyFrame) { | 162 if (frame_type == kEmptyFrame) { |
188 // kEmptyFrame is used to drive the DTMF when in CN mode | 163 // kEmptyFrame is used to drive the DTMF when in CN mode |
(...skipping 15 matching lines...) Expand all Loading... |
204 send = false; | 179 send = false; |
205 } | 180 } |
206 } else { | 181 } else { |
207 ended = true; | 182 ended = true; |
208 dtmf_event_is_on_ = false; | 183 dtmf_event_is_on_ = false; |
209 dtmf_time_last_sent_ = clock_->TimeInMilliseconds(); | 184 dtmf_time_last_sent_ = clock_->TimeInMilliseconds(); |
210 } | 185 } |
211 if (send) { | 186 if (send) { |
212 if (dtmf_duration_samples > 0xffff) { | 187 if (dtmf_duration_samples > 0xffff) { |
213 // RFC 4733 2.5.2.3 Long-Duration Events | 188 // RFC 4733 2.5.2.3 Long-Duration Events |
214 SendTelephoneEventPacket(ended, dtmf_payload_type, dtmf_timestamp_, | 189 SendTelephoneEventPacket(ended, dtmf_timestamp_, |
215 static_cast<uint16_t>(0xffff), false); | 190 static_cast<uint16_t>(0xffff), false); |
216 | 191 |
217 // set new timestap for this segment | 192 // set new timestap for this segment |
218 dtmf_timestamp_ = rtp_timestamp; | 193 dtmf_timestamp_ = rtp_timestamp; |
219 dtmf_duration_samples -= 0xffff; | 194 dtmf_duration_samples -= 0xffff; |
220 dtmf_length_samples_ -= 0xffff; | 195 dtmf_length_samples_ -= 0xffff; |
221 | 196 |
222 return SendTelephoneEventPacket( | 197 return SendTelephoneEventPacket(ended, dtmf_timestamp_, |
223 ended, dtmf_payload_type, dtmf_timestamp_, | |
224 static_cast<uint16_t>(dtmf_duration_samples), false); | 198 static_cast<uint16_t>(dtmf_duration_samples), false); |
225 } else { | 199 } else { |
226 if (!SendTelephoneEventPacket(ended, dtmf_payload_type, dtmf_timestamp_, | 200 if (!SendTelephoneEventPacket(ended, dtmf_timestamp_, |
227 dtmf_duration_samples, | 201 dtmf_duration_samples, |
228 !dtmf_event_first_packet_sent_)) { | 202 !dtmf_event_first_packet_sent_)) { |
229 return false; | 203 return false; |
230 } | 204 } |
231 dtmf_event_first_packet_sent_ = true; | 205 dtmf_event_first_packet_sent_ = true; |
232 return true; | 206 return true; |
233 } | 207 } |
234 } | 208 } |
235 return true; | 209 return true; |
236 } | 210 } |
237 if (payload_size == 0 || payload_data == NULL) { | 211 if (payload_size == 0 || payload_data == NULL) { |
238 if (frame_type == kEmptyFrame) { | 212 if (frame_type == kEmptyFrame) { |
239 // we don't send empty audio RTP packets | 213 // we don't send empty audio RTP packets |
240 // no error since we use it to drive DTMF when we use VAD | 214 // no error since we use it to drive DTMF when we use VAD |
241 return true; | 215 return true; |
242 } | 216 } |
243 return false; | 217 return false; |
244 } | 218 } |
| 219 |
245 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(); | 220 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(); |
246 packet->SetMarker(MarkerBit(frame_type, payload_type)); | 221 packet->SetMarker(MarkerBit(frame_type, payload_type)); |
247 packet->SetPayloadType(payload_type); | 222 packet->SetPayloadType(payload_type); |
248 packet->SetTimestamp(rtp_timestamp); | 223 packet->SetTimestamp(rtp_timestamp); |
249 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); | 224 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
250 // Update audio level extension, if included. | 225 // Update audio level extension, if included. |
251 packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech, | 226 packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech, |
252 audio_level_dbov); | 227 audio_level_dbov); |
253 | 228 |
254 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { | 229 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 } | 267 } |
293 rtc::CritScope cs(&send_audio_critsect_); | 268 rtc::CritScope cs(&send_audio_critsect_); |
294 audio_level_dbov_ = level_dbov; | 269 audio_level_dbov_ = level_dbov; |
295 return 0; | 270 return 0; |
296 } | 271 } |
297 | 272 |
298 // Send a TelephoneEvent tone using RFC 2833 (4733) | 273 // Send a TelephoneEvent tone using RFC 2833 (4733) |
299 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, | 274 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, |
300 uint16_t time_ms, | 275 uint16_t time_ms, |
301 uint8_t level) { | 276 uint8_t level) { |
| 277 DtmfQueue::Event event; |
302 { | 278 { |
303 rtc::CritScope lock(&send_audio_critsect_); | 279 rtc::CritScope lock(&send_audio_critsect_); |
304 if (dtmf_payload_type_ < 0) { | 280 if (dtmf_payload_type_ < 0) { |
305 // TelephoneEvent payloadtype not configured | 281 // TelephoneEvent payloadtype not configured |
306 return -1; | 282 return -1; |
307 } | 283 } |
| 284 event.payload_type = dtmf_payload_type_; |
308 } | 285 } |
309 return dtmf_queue_.AddDTMF(key, time_ms, level); | 286 event.key = key; |
| 287 event.duration_ms = time_ms; |
| 288 event.level = level; |
| 289 return dtmf_queue_.AddDtmf(event) ? 0 : -1; |
310 } | 290 } |
311 | 291 |
312 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, | 292 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, |
313 int8_t dtmf_payload_type, | |
314 uint32_t dtmf_timestamp, | 293 uint32_t dtmf_timestamp, |
315 uint16_t duration, | 294 uint16_t duration, |
316 bool marker_bit) { | 295 bool marker_bit) { |
317 uint8_t send_count = 1; | 296 uint8_t send_count = 1; |
318 bool result = true; | 297 bool result = true; |
319 | 298 |
320 if (ended) { | 299 if (ended) { |
321 // resend last packet in an event 3 times | 300 // resend last packet in an event 3 times |
322 send_count = 3; | 301 send_count = 3; |
323 } | 302 } |
324 do { | 303 do { |
325 // Send DTMF data. | 304 // Send DTMF data. |
326 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr; | 305 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr; |
327 constexpr size_t kDtmfSize = 4; | 306 constexpr size_t kDtmfSize = 4; |
328 std::unique_ptr<RtpPacketToSend> packet( | 307 std::unique_ptr<RtpPacketToSend> packet( |
329 new RtpPacketToSend(kNoExtensions, kRtpHeaderSize + kDtmfSize)); | 308 new RtpPacketToSend(kNoExtensions, kRtpHeaderSize + kDtmfSize)); |
330 packet->SetPayloadType(dtmf_payload_type); | 309 packet->SetPayloadType(dtmf_current_event_.payload_type); |
331 packet->SetMarker(marker_bit); | 310 packet->SetMarker(marker_bit); |
332 packet->SetSsrc(rtp_sender_->SSRC()); | 311 packet->SetSsrc(rtp_sender_->SSRC()); |
333 packet->SetTimestamp(dtmf_timestamp); | 312 packet->SetTimestamp(dtmf_timestamp); |
334 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); | 313 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
335 if (!rtp_sender_->AssignSequenceNumber(packet.get())) | 314 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
336 return false; | 315 return false; |
337 | 316 |
338 // Create DTMF data. | 317 // Create DTMF data. |
339 uint8_t* dtmfbuffer = packet->AllocatePayload(kDtmfSize); | 318 uint8_t* dtmfbuffer = packet->AllocatePayload(kDtmfSize); |
340 RTC_DCHECK(dtmfbuffer); | 319 RTC_DCHECK(dtmfbuffer); |
341 /* From RFC 2833: | 320 /* From RFC 2833: |
342 0 1 2 3 | 321 0 1 2 3 |
343 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 322 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
344 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 323 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
345 | event |E|R| volume | duration | | 324 | event |E|R| volume | duration | |
346 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 325 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
347 */ | 326 */ |
348 // R bit always cleared | 327 // R bit always cleared |
349 uint8_t R = 0x00; | 328 uint8_t R = 0x00; |
350 uint8_t volume = dtmf_level_; | 329 uint8_t volume = dtmf_current_event_.level; |
351 | 330 |
352 // First packet un-ended | 331 // First packet un-ended |
353 uint8_t E = ended ? 0x80 : 0x00; | 332 uint8_t E = ended ? 0x80 : 0x00; |
354 | 333 |
355 // First byte is Event number, equals key number | 334 // First byte is Event number, equals key number |
356 dtmfbuffer[0] = dtmf_key_; | 335 dtmfbuffer[0] = dtmf_current_event_.key; |
357 dtmfbuffer[1] = E | R | volume; | 336 dtmfbuffer[1] = E | R | volume; |
358 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration); | 337 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration); |
359 | 338 |
360 TRACE_EVENT_INSTANT2( | 339 TRACE_EVENT_INSTANT2( |
361 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", | 340 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", |
362 "timestamp", packet->Timestamp(), "seqnum", packet->SequenceNumber()); | 341 "timestamp", packet->Timestamp(), "seqnum", packet->SequenceNumber()); |
363 result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission, | 342 result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission, |
364 RtpPacketSender::kHighPriority); | 343 RtpPacketSender::kHighPriority); |
365 send_count--; | 344 send_count--; |
366 } while (send_count > 0 && result); | 345 } while (send_count > 0 && result); |
367 | 346 |
368 return result; | 347 return result; |
369 } | 348 } |
370 } // namespace webrtc | 349 } // namespace webrtc |
OLD | NEW |