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 {
RTPSenderAudio(const int32_t id,Clock * clock,RTPSender * rtpSender)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
~RTPSenderAudio()48 RTPSenderAudio::~RTPSenderAudio()
49 {
50 delete _sendAudioCritsect;
51 delete _audioFeedbackCritsect;
52 }
53
54 int32_t
RegisterAudioCallback(RtpAudioFeedback * messagesCallback)55 RTPSenderAudio::RegisterAudioCallback(RtpAudioFeedback* messagesCallback)
56 {
57 CriticalSectionScoped cs(_audioFeedbackCritsect);
58 _audioFeedback = messagesCallback;
59 return 0;
60 }
61
62 void
SetAudioFrequency(const uint32_t f)63 RTPSenderAudio::SetAudioFrequency(const uint32_t f)
64 {
65 CriticalSectionScoped cs(_sendAudioCritsect);
66 _frequency = f;
67 }
68
69 int
AudioFrequency() const70 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
SetAudioPacketSize(const uint16_t packetSizeSamples)78 RTPSenderAudio::SetAudioPacketSize(const uint16_t packetSizeSamples)
79 {
80 CriticalSectionScoped cs(_sendAudioCritsect);
81
82 _packetSizeSamples = packetSizeSamples;
83 return 0;
84 }
85
RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],const int8_t payloadType,const uint32_t frequency,const uint8_t channels,const uint32_t rate,ModuleRTPUtility::Payload * & payload)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 ModuleRTPUtility::Payload*& payload) {
93 CriticalSectionScoped cs(_sendAudioCritsect);
94
95 if (ModuleRTPUtility::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 (ModuleRTPUtility::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 ModuleRTPUtility::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
MarkerBit(const FrameType frameType,const int8_t payloadType)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
SendTelephoneEventActive(int8_t & telephoneEvent) const213 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
SendAudio(const FrameType frameType,const int8_t payloadType,const uint32_t captureTimeStamp,const uint8_t * payloadData,const uint32_t dataSize,const RTPFragmentationHeader * fragmentation)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 // set markerBit on the first packet in the burst
322 _dtmfEventFirstPacketSent = true;
323 return SendTelephoneEventPacket(
324 ended,
325 _dtmfTimestamp,
326 static_cast<uint16_t>(dtmfDurationSamples),
327 !_dtmfEventFirstPacketSent);
328 }
329 }
330 return 0;
331 }
332 _sendAudioCritsect->Leave();
333 }
334 if (payloadSize == 0 || payloadData == NULL) {
335 if (frameType == kFrameEmpty) {
336 // we don't send empty audio RTP packets
337 // no error since we use it to drive DTMF when we use VAD
338 return 0;
339 }
340 return -1;
341 }
342 uint8_t dataBuffer[IP_PACKET_SIZE];
343 bool markerBit = MarkerBit(frameType, payloadType);
344
345 int32_t rtpHeaderLength = 0;
346 uint16_t timestampOffset = 0;
347
348 if (_REDPayloadType >= 0 && fragmentation && !markerBit &&
349 fragmentation->fragmentationVectorSize > 1) {
350 // have we configured RED? use its payload type
351 // we need to get the current timestamp to calc the diff
352 uint32_t oldTimeStamp = _rtpSender->Timestamp();
353 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, _REDPayloadType,
354 markerBit, captureTimeStamp,
355 _clock->TimeInMilliseconds());
356
357 timestampOffset = uint16_t(_rtpSender->Timestamp() - oldTimeStamp);
358 } else {
359 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, payloadType,
360 markerBit, captureTimeStamp,
361 _clock->TimeInMilliseconds());
362 }
363 if (rtpHeaderLength <= 0) {
364 return -1;
365 }
366 if (maxPayloadLength < (rtpHeaderLength + payloadSize)) {
367 // Too large payload buffer.
368 return -1;
369 }
370 {
371 CriticalSectionScoped cs(_sendAudioCritsect);
372 if (_REDPayloadType >= 0 && // Have we configured RED?
373 fragmentation &&
374 fragmentation->fragmentationVectorSize > 1 &&
375 !markerBit) {
376 if (timestampOffset <= 0x3fff) {
377 if(fragmentation->fragmentationVectorSize != 2) {
378 // we only support 2 codecs when using RED
379 return -1;
380 }
381 // only 0x80 if we have multiple blocks
382 dataBuffer[rtpHeaderLength++] = 0x80 +
383 fragmentation->fragmentationPlType[1];
384 uint32_t blockLength = fragmentation->fragmentationLength[1];
385
386 // sanity blockLength
387 if(blockLength > 0x3ff) { // block length 10 bits 1023 bytes
388 return -1;
389 }
390 uint32_t REDheader = (timestampOffset << 10) + blockLength;
391 ModuleRTPUtility::AssignUWord24ToBuffer(dataBuffer + rtpHeaderLength,
392 REDheader);
393 rtpHeaderLength += 3;
394
395 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
396 // copy the RED data
397 memcpy(dataBuffer+rtpHeaderLength,
398 payloadData + fragmentation->fragmentationOffset[1],
399 fragmentation->fragmentationLength[1]);
400
401 // copy the normal data
402 memcpy(dataBuffer+rtpHeaderLength +
403 fragmentation->fragmentationLength[1],
404 payloadData + fragmentation->fragmentationOffset[0],
405 fragmentation->fragmentationLength[0]);
406
407 payloadSize = static_cast<uint16_t>(
408 fragmentation->fragmentationLength[0] +
409 fragmentation->fragmentationLength[1]);
410 } else {
411 // silence for too long send only new data
412 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
413 memcpy(dataBuffer+rtpHeaderLength,
414 payloadData + fragmentation->fragmentationOffset[0],
415 fragmentation->fragmentationLength[0]);
416
417 payloadSize = static_cast<uint16_t>(
418 fragmentation->fragmentationLength[0]);
419 }
420 } else {
421 if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
422 // use the fragment info if we have one
423 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
424 memcpy( dataBuffer+rtpHeaderLength,
425 payloadData + fragmentation->fragmentationOffset[0],
426 fragmentation->fragmentationLength[0]);
427
428 payloadSize = static_cast<uint16_t>(
429 fragmentation->fragmentationLength[0]);
430 } else {
431 memcpy(dataBuffer+rtpHeaderLength, payloadData, payloadSize);
432 }
433 }
434 _lastPayloadType = payloadType;
435
436 // Update audio level extension, if included.
437 {
438 uint16_t packetSize = payloadSize + rtpHeaderLength;
439 ModuleRTPUtility::RTPHeaderParser rtp_parser(dataBuffer, packetSize);
440 RTPHeader rtp_header;
441 rtp_parser.Parse(rtp_header);
442 _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
443 (frameType == kAudioFrameSpeech),
444 _audioLevel_dBov);
445 }
446 } // end critical section
447 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp,
448 "timestamp", _rtpSender->Timestamp(),
449 "seqnum", _rtpSender->SequenceNumber());
450 return _rtpSender->SendToNetwork(dataBuffer,
451 payloadSize,
452 static_cast<uint16_t>(rtpHeaderLength),
453 -1,
454 kAllowRetransmission,
455 PacedSender::kHighPriority);
456 }
457
458 // Audio level magnitude and voice activity flag are set for each RTP packet
459 int32_t
SetAudioLevel(const uint8_t level_dBov)460 RTPSenderAudio::SetAudioLevel(const uint8_t level_dBov)
461 {
462 if (level_dBov > 127)
463 {
464 return -1;
465 }
466 CriticalSectionScoped cs(_sendAudioCritsect);
467 _audioLevel_dBov = level_dBov;
468 return 0;
469 }
470
471 // Set payload type for Redundant Audio Data RFC 2198
472 int32_t
SetRED(const int8_t payloadType)473 RTPSenderAudio::SetRED(const int8_t payloadType)
474 {
475 if(payloadType < -1 )
476 {
477 return -1;
478 }
479 _REDPayloadType = payloadType;
480 return 0;
481 }
482
483 // Get payload type for Redundant Audio Data RFC 2198
484 int32_t
RED(int8_t & payloadType) const485 RTPSenderAudio::RED(int8_t& payloadType) const
486 {
487 if(_REDPayloadType == -1)
488 {
489 // not configured
490 return -1;
491 }
492 payloadType = _REDPayloadType;
493 return 0;
494 }
495
496 // Send a TelephoneEvent tone using RFC 2833 (4733)
497 int32_t
SendTelephoneEvent(const uint8_t key,const uint16_t time_ms,const uint8_t level)498 RTPSenderAudio::SendTelephoneEvent(const uint8_t key,
499 const uint16_t time_ms,
500 const uint8_t level)
501 {
502 // DTMF is protected by its own critsect
503 if(_dtmfPayloadType < 0)
504 {
505 // TelephoneEvent payloadtype not configured
506 return -1;
507 }
508 return AddDTMF(key, time_ms, level);
509 }
510
511 int32_t
SendTelephoneEventPacket(const bool ended,const uint32_t dtmfTimeStamp,const uint16_t duration,const bool markerBit)512 RTPSenderAudio::SendTelephoneEventPacket(const bool ended,
513 const uint32_t dtmfTimeStamp,
514 const uint16_t duration,
515 const bool markerBit)
516 {
517 uint8_t dtmfbuffer[IP_PACKET_SIZE];
518 uint8_t sendCount = 1;
519 int32_t retVal = 0;
520
521 if(ended)
522 {
523 // resend last packet in an event 3 times
524 sendCount = 3;
525 }
526 do
527 {
528 _sendAudioCritsect->Enter();
529
530 //Send DTMF data
531 _rtpSender->BuildRTPheader(dtmfbuffer, _dtmfPayloadType, markerBit,
532 dtmfTimeStamp, _clock->TimeInMilliseconds());
533
534 // reset CSRC and X bit
535 dtmfbuffer[0] &= 0xe0;
536
537 //Create DTMF data
538 /* From RFC 2833:
539
540 0 1 2 3
541 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
542 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
543 | event |E|R| volume | duration |
544 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
545 */
546 // R bit always cleared
547 uint8_t R = 0x00;
548 uint8_t volume = _dtmfLevel;
549
550 // First packet un-ended
551 uint8_t E = 0x00;
552
553 if(ended)
554 {
555 E = 0x80;
556 }
557
558 // First byte is Event number, equals key number
559 dtmfbuffer[12] = _dtmfKey;
560 dtmfbuffer[13] = E|R|volume;
561 ModuleRTPUtility::AssignUWord16ToBuffer(dtmfbuffer+14, duration);
562
563 _sendAudioCritsect->Leave();
564 TRACE_EVENT_INSTANT2("webrtc_rtp",
565 "Audio::SendTelephoneEvent",
566 "timestamp", dtmfTimeStamp,
567 "seqnum", _rtpSender->SequenceNumber());
568 retVal = _rtpSender->SendToNetwork(dtmfbuffer, 4, 12, -1,
569 kAllowRetransmission,
570 PacedSender::kHighPriority);
571 sendCount--;
572
573 }while (sendCount > 0 && retVal == 0);
574
575 return retVal;
576 }
577 } // namespace webrtc
578