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