| 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 |