1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h" 12 13 #include <assert.h> //assert 14 #include <string.h> //memcpy 15 16 #include "webrtc/system_wrappers/interface/trace_event.h" 17 18 namespace webrtc { 19 RTPSenderAudio::RTPSenderAudio(const int32_t id, Clock* clock, 20 RTPSender* rtpSender) : 21 _id(id), 22 _clock(clock), 23 _rtpSender(rtpSender), 24 _audioFeedbackCritsect(CriticalSectionWrapper::CreateCriticalSection()), 25 _audioFeedback(NULL), 26 _sendAudioCritsect(CriticalSectionWrapper::CreateCriticalSection()), 27 _frequency(8000), 28 _packetSizeSamples(160), 29 _dtmfEventIsOn(false), 30 _dtmfEventFirstPacketSent(false), 31 _dtmfPayloadType(-1), 32 _dtmfTimestamp(0), 33 _dtmfKey(0), 34 _dtmfLengthSamples(0), 35 _dtmfLevel(0), 36 _dtmfTimeLastSent(0), 37 _dtmfTimestampLastSent(0), 38 _REDPayloadType(-1), 39 _inbandVADactive(false), 40 _cngNBPayloadType(-1), 41 _cngWBPayloadType(-1), 42 _cngSWBPayloadType(-1), 43 _cngFBPayloadType(-1), 44 _lastPayloadType(-1), 45 _audioLevel_dBov(0) { 46 }; 47 48 RTPSenderAudio::~RTPSenderAudio() 49 { 50 delete _sendAudioCritsect; 51 delete _audioFeedbackCritsect; 52 } 53 54 int32_t 55 RTPSenderAudio::RegisterAudioCallback(RtpAudioFeedback* messagesCallback) 56 { 57 CriticalSectionScoped cs(_audioFeedbackCritsect); 58 _audioFeedback = messagesCallback; 59 return 0; 60 } 61 62 void 63 RTPSenderAudio::SetAudioFrequency(const uint32_t f) 64 { 65 CriticalSectionScoped cs(_sendAudioCritsect); 66 _frequency = f; 67 } 68 69 int 70 RTPSenderAudio::AudioFrequency() const 71 { 72 CriticalSectionScoped cs(_sendAudioCritsect); 73 return _frequency; 74 } 75 76 // set audio packet size, used to determine when it's time to send a DTMF packet in silence (CNG) 77 int32_t 78 RTPSenderAudio::SetAudioPacketSize(const uint16_t packetSizeSamples) 79 { 80 CriticalSectionScoped cs(_sendAudioCritsect); 81 82 _packetSizeSamples = packetSizeSamples; 83 return 0; 84 } 85 86 int32_t RTPSenderAudio::RegisterAudioPayload( 87 const char payloadName[RTP_PAYLOAD_NAME_SIZE], 88 const int8_t payloadType, 89 const uint32_t frequency, 90 const uint8_t channels, 91 const uint32_t rate, 92 RtpUtility::Payload*& payload) { 93 CriticalSectionScoped cs(_sendAudioCritsect); 94 95 if (RtpUtility::StringCompare(payloadName, "cn", 2)) { 96 // we can have multiple CNG payload types 97 if (frequency == 8000) { 98 _cngNBPayloadType = payloadType; 99 100 } else if (frequency == 16000) { 101 _cngWBPayloadType = payloadType; 102 103 } else if (frequency == 32000) { 104 _cngSWBPayloadType = payloadType; 105 106 } else if (frequency == 48000) { 107 _cngFBPayloadType = payloadType; 108 109 } else { 110 return -1; 111 } 112 } 113 if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) { 114 // Don't add it to the list 115 // we dont want to allow send with a DTMF payloadtype 116 _dtmfPayloadType = payloadType; 117 return 0; 118 // The default timestamp rate is 8000 Hz, but other rates may be defined. 119 } 120 payload = new RtpUtility::Payload; 121 payload->typeSpecific.Audio.frequency = frequency; 122 payload->typeSpecific.Audio.channels = channels; 123 payload->typeSpecific.Audio.rate = rate; 124 payload->audio = true; 125 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; 126 strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 127 return 0; 128 } 129 130 bool 131 RTPSenderAudio::MarkerBit(const FrameType frameType, 132 const int8_t payloadType) 133 { 134 CriticalSectionScoped cs(_sendAudioCritsect); 135 136 // for audio true for first packet in a speech burst 137 bool markerBit = false; 138 if(_lastPayloadType != payloadType) 139 { 140 if(_cngNBPayloadType != -1) 141 { 142 // we have configured NB CNG 143 if(_cngNBPayloadType == payloadType) 144 { 145 // only set a marker bit when we change payload type to a non CNG 146 return false; 147 } 148 } 149 if(_cngWBPayloadType != -1) 150 { 151 // we have configured WB CNG 152 if(_cngWBPayloadType == payloadType) 153 { 154 // only set a marker bit when we change payload type to a non CNG 155 return false; 156 } 157 } 158 if(_cngSWBPayloadType != -1) 159 { 160 // we have configured SWB CNG 161 if(_cngSWBPayloadType == payloadType) 162 { 163 // only set a marker bit when we change payload type to a non CNG 164 return false; 165 } 166 } 167 if(_cngFBPayloadType != -1) 168 { 169 // we have configured SWB CNG 170 if(_cngFBPayloadType == payloadType) 171 { 172 // only set a marker bit when we change payload type to a non CNG 173 return false; 174 } 175 } 176 // payloadType differ 177 if(_lastPayloadType == -1) 178 { 179 if(frameType != kAudioFrameCN) 180 { 181 // first packet and NOT CNG 182 return true; 183 184 }else 185 { 186 // first packet and CNG 187 _inbandVADactive = true; 188 return false; 189 } 190 } 191 // not first packet AND 192 // not CNG AND 193 // payloadType changed 194 195 // set a marker bit when we change payload type 196 markerBit = true; 197 } 198 199 // For G.723 G.729, AMR etc we can have inband VAD 200 if(frameType == kAudioFrameCN) 201 { 202 _inbandVADactive = true; 203 204 } else if(_inbandVADactive) 205 { 206 _inbandVADactive = false; 207 markerBit = true; 208 } 209 return markerBit; 210 } 211 212 bool 213 RTPSenderAudio::SendTelephoneEventActive(int8_t& telephoneEvent) const 214 { 215 if(_dtmfEventIsOn) 216 { 217 telephoneEvent = _dtmfKey; 218 return true; 219 } 220 int64_t delaySinceLastDTMF = _clock->TimeInMilliseconds() - 221 _dtmfTimeLastSent; 222 if(delaySinceLastDTMF < 100) 223 { 224 telephoneEvent = _dtmfKey; 225 return true; 226 } 227 telephoneEvent = -1; 228 return false; 229 } 230 231 int32_t RTPSenderAudio::SendAudio( 232 const FrameType frameType, 233 const int8_t payloadType, 234 const uint32_t captureTimeStamp, 235 const uint8_t* payloadData, 236 const uint32_t dataSize, 237 const RTPFragmentationHeader* fragmentation) { 238 // TODO(pwestin) Breakup function in smaller functions. 239 uint16_t payloadSize = static_cast<uint16_t>(dataSize); 240 uint16_t maxPayloadLength = _rtpSender->MaxPayloadLength(); 241 bool dtmfToneStarted = false; 242 uint16_t dtmfLengthMS = 0; 243 uint8_t key = 0; 244 245 // Check if we have pending DTMFs to send 246 if (!_dtmfEventIsOn && PendingDTMF()) { 247 CriticalSectionScoped cs(_sendAudioCritsect); 248 249 int64_t delaySinceLastDTMF = _clock->TimeInMilliseconds() - 250 _dtmfTimeLastSent; 251 252 if (delaySinceLastDTMF > 100) { 253 // New tone to play 254 _dtmfTimestamp = captureTimeStamp; 255 if (NextDTMF(&key, &dtmfLengthMS, &_dtmfLevel) >= 0) { 256 _dtmfEventFirstPacketSent = false; 257 _dtmfKey = key; 258 _dtmfLengthSamples = (_frequency / 1000) * dtmfLengthMS; 259 dtmfToneStarted = true; 260 _dtmfEventIsOn = true; 261 } 262 } 263 } 264 if (dtmfToneStarted) { 265 CriticalSectionScoped cs(_audioFeedbackCritsect); 266 if (_audioFeedback) { 267 _audioFeedback->OnPlayTelephoneEvent(_id, key, dtmfLengthMS, _dtmfLevel); 268 } 269 } 270 271 // A source MAY send events and coded audio packets for the same time 272 // but we don't support it 273 { 274 _sendAudioCritsect->Enter(); 275 276 if (_dtmfEventIsOn) { 277 if (frameType == kFrameEmpty) { 278 // kFrameEmpty is used to drive the DTMF when in CN mode 279 // it can be triggered more frequently than we want to send the 280 // DTMF packets. 281 if (_packetSizeSamples > (captureTimeStamp - _dtmfTimestampLastSent)) { 282 // not time to send yet 283 _sendAudioCritsect->Leave(); 284 return 0; 285 } 286 } 287 _dtmfTimestampLastSent = captureTimeStamp; 288 uint32_t dtmfDurationSamples = captureTimeStamp - _dtmfTimestamp; 289 bool ended = false; 290 bool send = true; 291 292 if (_dtmfLengthSamples > dtmfDurationSamples) { 293 if (dtmfDurationSamples <= 0) { 294 // Skip send packet at start, since we shouldn't use duration 0 295 send = false; 296 } 297 } else { 298 ended = true; 299 _dtmfEventIsOn = false; 300 _dtmfTimeLastSent = _clock->TimeInMilliseconds(); 301 } 302 // don't hold the critsect while calling SendTelephoneEventPacket 303 _sendAudioCritsect->Leave(); 304 if (send) { 305 if (dtmfDurationSamples > 0xffff) { 306 // RFC 4733 2.5.2.3 Long-Duration Events 307 SendTelephoneEventPacket(ended, _dtmfTimestamp, 308 static_cast<uint16_t>(0xffff), false); 309 310 // set new timestap for this segment 311 _dtmfTimestamp = captureTimeStamp; 312 dtmfDurationSamples -= 0xffff; 313 _dtmfLengthSamples -= 0xffff; 314 315 return SendTelephoneEventPacket( 316 ended, 317 _dtmfTimestamp, 318 static_cast<uint16_t>(dtmfDurationSamples), 319 false); 320 } else { 321 if (SendTelephoneEventPacket( 322 ended, 323 _dtmfTimestamp, 324 static_cast<uint16_t>(dtmfDurationSamples), 325 !_dtmfEventFirstPacketSent) != 0) { 326 return -1; 327 } 328 _dtmfEventFirstPacketSent = true; 329 return 0; 330 } 331 } 332 return 0; 333 } 334 _sendAudioCritsect->Leave(); 335 } 336 if (payloadSize == 0 || payloadData == NULL) { 337 if (frameType == kFrameEmpty) { 338 // we don't send empty audio RTP packets 339 // no error since we use it to drive DTMF when we use VAD 340 return 0; 341 } 342 return -1; 343 } 344 uint8_t dataBuffer[IP_PACKET_SIZE]; 345 bool markerBit = MarkerBit(frameType, payloadType); 346 347 int32_t rtpHeaderLength = 0; 348 uint16_t timestampOffset = 0; 349 350 if (_REDPayloadType >= 0 && fragmentation && !markerBit && 351 fragmentation->fragmentationVectorSize > 1) { 352 // have we configured RED? use its payload type 353 // we need to get the current timestamp to calc the diff 354 uint32_t oldTimeStamp = _rtpSender->Timestamp(); 355 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, _REDPayloadType, 356 markerBit, captureTimeStamp, 357 _clock->TimeInMilliseconds()); 358 359 timestampOffset = uint16_t(_rtpSender->Timestamp() - oldTimeStamp); 360 } else { 361 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, payloadType, 362 markerBit, captureTimeStamp, 363 _clock->TimeInMilliseconds()); 364 } 365 if (rtpHeaderLength <= 0) { 366 return -1; 367 } 368 if (maxPayloadLength < (rtpHeaderLength + payloadSize)) { 369 // Too large payload buffer. 370 return -1; 371 } 372 { 373 CriticalSectionScoped cs(_sendAudioCritsect); 374 if (_REDPayloadType >= 0 && // Have we configured RED? 375 fragmentation && 376 fragmentation->fragmentationVectorSize > 1 && 377 !markerBit) { 378 if (timestampOffset <= 0x3fff) { 379 if(fragmentation->fragmentationVectorSize != 2) { 380 // we only support 2 codecs when using RED 381 return -1; 382 } 383 // only 0x80 if we have multiple blocks 384 dataBuffer[rtpHeaderLength++] = 0x80 + 385 fragmentation->fragmentationPlType[1]; 386 uint32_t blockLength = fragmentation->fragmentationLength[1]; 387 388 // sanity blockLength 389 if(blockLength > 0x3ff) { // block length 10 bits 1023 bytes 390 return -1; 391 } 392 uint32_t REDheader = (timestampOffset << 10) + blockLength; 393 RtpUtility::AssignUWord24ToBuffer(dataBuffer + rtpHeaderLength, 394 REDheader); 395 rtpHeaderLength += 3; 396 397 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 398 // copy the RED data 399 memcpy(dataBuffer+rtpHeaderLength, 400 payloadData + fragmentation->fragmentationOffset[1], 401 fragmentation->fragmentationLength[1]); 402 403 // copy the normal data 404 memcpy(dataBuffer+rtpHeaderLength + 405 fragmentation->fragmentationLength[1], 406 payloadData + fragmentation->fragmentationOffset[0], 407 fragmentation->fragmentationLength[0]); 408 409 payloadSize = static_cast<uint16_t>( 410 fragmentation->fragmentationLength[0] + 411 fragmentation->fragmentationLength[1]); 412 } else { 413 // silence for too long send only new data 414 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 415 memcpy(dataBuffer+rtpHeaderLength, 416 payloadData + fragmentation->fragmentationOffset[0], 417 fragmentation->fragmentationLength[0]); 418 419 payloadSize = static_cast<uint16_t>( 420 fragmentation->fragmentationLength[0]); 421 } 422 } else { 423 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { 424 // use the fragment info if we have one 425 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 426 memcpy( dataBuffer+rtpHeaderLength, 427 payloadData + fragmentation->fragmentationOffset[0], 428 fragmentation->fragmentationLength[0]); 429 430 payloadSize = static_cast<uint16_t>( 431 fragmentation->fragmentationLength[0]); 432 } else { 433 memcpy(dataBuffer+rtpHeaderLength, payloadData, payloadSize); 434 } 435 } 436 _lastPayloadType = payloadType; 437 438 // Update audio level extension, if included. 439 { 440 uint16_t packetSize = payloadSize + rtpHeaderLength; 441 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); 442 RTPHeader rtp_header; 443 rtp_parser.Parse(rtp_header); 444 _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header, 445 (frameType == kAudioFrameSpeech), 446 _audioLevel_dBov); 447 } 448 } // end critical section 449 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, 450 "timestamp", _rtpSender->Timestamp(), 451 "seqnum", _rtpSender->SequenceNumber()); 452 return _rtpSender->SendToNetwork(dataBuffer, 453 payloadSize, 454 static_cast<uint16_t>(rtpHeaderLength), 455 -1, 456 kAllowRetransmission, 457 PacedSender::kHighPriority); 458 } 459 460 // Audio level magnitude and voice activity flag are set for each RTP packet 461 int32_t 462 RTPSenderAudio::SetAudioLevel(const uint8_t level_dBov) 463 { 464 if (level_dBov > 127) 465 { 466 return -1; 467 } 468 CriticalSectionScoped cs(_sendAudioCritsect); 469 _audioLevel_dBov = level_dBov; 470 return 0; 471 } 472 473 // Set payload type for Redundant Audio Data RFC 2198 474 int32_t 475 RTPSenderAudio::SetRED(const int8_t payloadType) 476 { 477 if(payloadType < -1 ) 478 { 479 return -1; 480 } 481 _REDPayloadType = payloadType; 482 return 0; 483 } 484 485 // Get payload type for Redundant Audio Data RFC 2198 486 int32_t 487 RTPSenderAudio::RED(int8_t& payloadType) const 488 { 489 if(_REDPayloadType == -1) 490 { 491 // not configured 492 return -1; 493 } 494 payloadType = _REDPayloadType; 495 return 0; 496 } 497 498 // Send a TelephoneEvent tone using RFC 2833 (4733) 499 int32_t 500 RTPSenderAudio::SendTelephoneEvent(const uint8_t key, 501 const uint16_t time_ms, 502 const uint8_t level) 503 { 504 // DTMF is protected by its own critsect 505 if(_dtmfPayloadType < 0) 506 { 507 // TelephoneEvent payloadtype not configured 508 return -1; 509 } 510 return AddDTMF(key, time_ms, level); 511 } 512 513 int32_t 514 RTPSenderAudio::SendTelephoneEventPacket(const bool ended, 515 const uint32_t dtmfTimeStamp, 516 const uint16_t duration, 517 const bool markerBit) 518 { 519 uint8_t dtmfbuffer[IP_PACKET_SIZE]; 520 uint8_t sendCount = 1; 521 int32_t retVal = 0; 522 523 if(ended) 524 { 525 // resend last packet in an event 3 times 526 sendCount = 3; 527 } 528 do 529 { 530 _sendAudioCritsect->Enter(); 531 532 //Send DTMF data 533 _rtpSender->BuildRTPheader(dtmfbuffer, _dtmfPayloadType, markerBit, 534 dtmfTimeStamp, _clock->TimeInMilliseconds()); 535 536 // reset CSRC and X bit 537 dtmfbuffer[0] &= 0xe0; 538 539 //Create DTMF data 540 /* From RFC 2833: 541 542 0 1 2 3 543 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 544 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 545 | event |E|R| volume | duration | 546 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 547 */ 548 // R bit always cleared 549 uint8_t R = 0x00; 550 uint8_t volume = _dtmfLevel; 551 552 // First packet un-ended 553 uint8_t E = 0x00; 554 555 if(ended) 556 { 557 E = 0x80; 558 } 559 560 // First byte is Event number, equals key number 561 dtmfbuffer[12] = _dtmfKey; 562 dtmfbuffer[13] = E|R|volume; 563 RtpUtility::AssignUWord16ToBuffer(dtmfbuffer + 14, duration); 564 565 _sendAudioCritsect->Leave(); 566 TRACE_EVENT_INSTANT2("webrtc_rtp", 567 "Audio::SendTelephoneEvent", 568 "timestamp", dtmfTimeStamp, 569 "seqnum", _rtpSender->SequenceNumber()); 570 retVal = _rtpSender->SendToNetwork(dtmfbuffer, 4, 12, -1, 571 kAllowRetransmission, 572 PacedSender::kHighPriority); 573 sendCount--; 574 575 }while (sendCount > 0 && retVal == 0); 576 577 return retVal; 578 } 579 } // namespace webrtc 580