Home | History | Annotate | Download | only in source
      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