| 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 "webrtc/base/logging.h" | 15 #include "webrtc/base/logging.h" | 
| 16 #include "webrtc/base/trace_event.h" | 16 #include "webrtc/base/trace_event.h" | 
| 17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 
| 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 
| 19 #include "webrtc/system_wrappers/include/tick_util.h" | 19 #include "webrtc/system_wrappers/include/tick_util.h" | 
| 20 | 20 | 
| 21 namespace webrtc { | 21 namespace webrtc { | 
| 22 | 22 | 
| 23 static const int kDtmfFrequencyHz = 8000; | 23 static const int kDtmfFrequencyHz = 8000; | 
| 24 | 24 | 
| 25 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtpSender) | 25 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtpSender) | 
| 26     : _clock(clock), | 26     : _clock(clock), | 
| 27       _rtpSender(rtpSender), | 27       _rtpSender(rtpSender), | 
| 28       _sendAudioCritsect(CriticalSectionWrapper::CreateCriticalSection()), |  | 
| 29       _packetSizeSamples(160), | 28       _packetSizeSamples(160), | 
| 30       _dtmfEventIsOn(false), | 29       _dtmfEventIsOn(false), | 
| 31       _dtmfEventFirstPacketSent(false), | 30       _dtmfEventFirstPacketSent(false), | 
| 32       _dtmfPayloadType(-1), | 31       _dtmfPayloadType(-1), | 
| 33       _dtmfTimestamp(0), | 32       _dtmfTimestamp(0), | 
| 34       _dtmfKey(0), | 33       _dtmfKey(0), | 
| 35       _dtmfLengthSamples(0), | 34       _dtmfLengthSamples(0), | 
| 36       _dtmfLevel(0), | 35       _dtmfLevel(0), | 
| 37       _dtmfTimeLastSent(0), | 36       _dtmfTimeLastSent(0), | 
| 38       _dtmfTimestampLastSent(0), | 37       _dtmfTimestampLastSent(0), | 
| 39       _REDPayloadType(-1), | 38       _REDPayloadType(-1), | 
| 40       _inbandVADactive(false), | 39       _inbandVADactive(false), | 
| 41       _cngNBPayloadType(-1), | 40       _cngNBPayloadType(-1), | 
| 42       _cngWBPayloadType(-1), | 41       _cngWBPayloadType(-1), | 
| 43       _cngSWBPayloadType(-1), | 42       _cngSWBPayloadType(-1), | 
| 44       _cngFBPayloadType(-1), | 43       _cngFBPayloadType(-1), | 
| 45       _lastPayloadType(-1), | 44       _lastPayloadType(-1), | 
| 46       _audioLevel_dBov(0) {} | 45       _audioLevel_dBov(0) {} | 
| 47 | 46 | 
| 48 RTPSenderAudio::~RTPSenderAudio() {} | 47 RTPSenderAudio::~RTPSenderAudio() {} | 
| 49 | 48 | 
| 50 int RTPSenderAudio::AudioFrequency() const { | 49 int RTPSenderAudio::AudioFrequency() const { | 
| 51   return kDtmfFrequencyHz; | 50   return kDtmfFrequencyHz; | 
| 52 } | 51 } | 
| 53 | 52 | 
| 54 // set audio packet size, used to determine when it's time to send a DTMF packet | 53 // set audio packet size, used to determine when it's time to send a DTMF packet | 
| 55 // in silence (CNG) | 54 // in silence (CNG) | 
| 56 int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packetSizeSamples) { | 55 int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packetSizeSamples) { | 
| 57   CriticalSectionScoped cs(_sendAudioCritsect.get()); | 56   rtc::CritScope cs(&_sendAudioCritsect); | 
| 58 | 57 | 
| 59   _packetSizeSamples = packetSizeSamples; | 58   _packetSizeSamples = packetSizeSamples; | 
| 60   return 0; | 59   return 0; | 
| 61 } | 60 } | 
| 62 | 61 | 
| 63 int32_t RTPSenderAudio::RegisterAudioPayload( | 62 int32_t RTPSenderAudio::RegisterAudioPayload( | 
| 64     const char payloadName[RTP_PAYLOAD_NAME_SIZE], | 63     const char payloadName[RTP_PAYLOAD_NAME_SIZE], | 
| 65     const int8_t payloadType, | 64     const int8_t payloadType, | 
| 66     const uint32_t frequency, | 65     const uint32_t frequency, | 
| 67     const size_t channels, | 66     const size_t channels, | 
| 68     const uint32_t rate, | 67     const uint32_t rate, | 
| 69     RtpUtility::Payload** payload) { | 68     RtpUtility::Payload** payload) { | 
| 70   if (RtpUtility::StringCompare(payloadName, "cn", 2)) { | 69   if (RtpUtility::StringCompare(payloadName, "cn", 2)) { | 
| 71     CriticalSectionScoped cs(_sendAudioCritsect.get()); | 70     rtc::CritScope cs(&_sendAudioCritsect); | 
| 72     //  we can have multiple CNG payload types | 71     //  we can have multiple CNG payload types | 
| 73     switch (frequency) { | 72     switch (frequency) { | 
| 74       case 8000: | 73       case 8000: | 
| 75         _cngNBPayloadType = payloadType; | 74         _cngNBPayloadType = payloadType; | 
| 76         break; | 75         break; | 
| 77       case 16000: | 76       case 16000: | 
| 78         _cngWBPayloadType = payloadType; | 77         _cngWBPayloadType = payloadType; | 
| 79         break; | 78         break; | 
| 80       case 32000: | 79       case 32000: | 
| 81         _cngSWBPayloadType = payloadType; | 80         _cngSWBPayloadType = payloadType; | 
| 82         break; | 81         break; | 
| 83       case 48000: | 82       case 48000: | 
| 84         _cngFBPayloadType = payloadType; | 83         _cngFBPayloadType = payloadType; | 
| 85         break; | 84         break; | 
| 86       default: | 85       default: | 
| 87         return -1; | 86         return -1; | 
| 88     } | 87     } | 
| 89   } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) { | 88   } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) { | 
| 90     CriticalSectionScoped cs(_sendAudioCritsect.get()); | 89     rtc::CritScope cs(&_sendAudioCritsect); | 
| 91     // Don't add it to the list | 90     // Don't add it to the list | 
| 92     // we dont want to allow send with a DTMF payloadtype | 91     // we dont want to allow send with a DTMF payloadtype | 
| 93     _dtmfPayloadType = payloadType; | 92     _dtmfPayloadType = payloadType; | 
| 94     return 0; | 93     return 0; | 
| 95     // The default timestamp rate is 8000 Hz, but other rates may be defined. | 94     // The default timestamp rate is 8000 Hz, but other rates may be defined. | 
| 96   } | 95   } | 
| 97   *payload = new RtpUtility::Payload; | 96   *payload = new RtpUtility::Payload; | 
| 98   (*payload)->typeSpecific.Audio.frequency = frequency; | 97   (*payload)->typeSpecific.Audio.frequency = frequency; | 
| 99   (*payload)->typeSpecific.Audio.channels = channels; | 98   (*payload)->typeSpecific.Audio.channels = channels; | 
| 100   (*payload)->typeSpecific.Audio.rate = rate; | 99   (*payload)->typeSpecific.Audio.rate = rate; | 
| 101   (*payload)->audio = true; | 100   (*payload)->audio = true; | 
| 102   (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0'; | 101   (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0'; | 
| 103   strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); | 102   strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); | 
| 104   return 0; | 103   return 0; | 
| 105 } | 104 } | 
| 106 | 105 | 
| 107 bool RTPSenderAudio::MarkerBit(FrameType frameType, int8_t payload_type) { | 106 bool RTPSenderAudio::MarkerBit(FrameType frameType, int8_t payload_type) { | 
| 108   CriticalSectionScoped cs(_sendAudioCritsect.get()); | 107   rtc::CritScope cs(&_sendAudioCritsect); | 
| 109   // for audio true for first packet in a speech burst | 108   // for audio true for first packet in a speech burst | 
| 110   bool markerBit = false; | 109   bool markerBit = false; | 
| 111   if (_lastPayloadType != payload_type) { | 110   if (_lastPayloadType != payload_type) { | 
| 112     if (payload_type != -1 && (_cngNBPayloadType == payload_type || | 111     if (payload_type != -1 && (_cngNBPayloadType == payload_type || | 
| 113                                _cngWBPayloadType == payload_type || | 112                                _cngWBPayloadType == payload_type || | 
| 114                                _cngSWBPayloadType == payload_type || | 113                                _cngSWBPayloadType == payload_type || | 
| 115                                _cngFBPayloadType == payload_type)) { | 114                                _cngFBPayloadType == payload_type)) { | 
| 116       // Only set a marker bit when we change payload type to a non CNG | 115       // Only set a marker bit when we change payload type to a non CNG | 
| 117       return false; | 116       return false; | 
| 118     } | 117     } | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 156   // TODO(pwestin) Breakup function in smaller functions. | 155   // TODO(pwestin) Breakup function in smaller functions. | 
| 157   size_t payloadSize = dataSize; | 156   size_t payloadSize = dataSize; | 
| 158   size_t maxPayloadLength = _rtpSender->MaxPayloadLength(); | 157   size_t maxPayloadLength = _rtpSender->MaxPayloadLength(); | 
| 159   uint16_t dtmfLengthMS = 0; | 158   uint16_t dtmfLengthMS = 0; | 
| 160   uint8_t key = 0; | 159   uint8_t key = 0; | 
| 161   int red_payload_type; | 160   int red_payload_type; | 
| 162   uint8_t audio_level_dbov; | 161   uint8_t audio_level_dbov; | 
| 163   int8_t dtmf_payload_type; | 162   int8_t dtmf_payload_type; | 
| 164   uint16_t packet_size_samples; | 163   uint16_t packet_size_samples; | 
| 165   { | 164   { | 
| 166     CriticalSectionScoped cs(_sendAudioCritsect.get()); | 165     rtc::CritScope cs(&_sendAudioCritsect); | 
| 167     red_payload_type = _REDPayloadType; | 166     red_payload_type = _REDPayloadType; | 
| 168     audio_level_dbov = _audioLevel_dBov; | 167     audio_level_dbov = _audioLevel_dBov; | 
| 169     dtmf_payload_type = _dtmfPayloadType; | 168     dtmf_payload_type = _dtmfPayloadType; | 
| 170     packet_size_samples = _packetSizeSamples; | 169     packet_size_samples = _packetSizeSamples; | 
| 171   } | 170   } | 
| 172 | 171 | 
| 173   // Check if we have pending DTMFs to send | 172   // Check if we have pending DTMFs to send | 
| 174   if (!_dtmfEventIsOn && PendingDTMF()) { | 173   if (!_dtmfEventIsOn && PendingDTMF()) { | 
| 175     int64_t delaySinceLastDTMF = | 174     int64_t delaySinceLastDTMF = | 
| 176         _clock->TimeInMilliseconds() - _dtmfTimeLastSent; | 175         _clock->TimeInMilliseconds() - _dtmfTimeLastSent; | 
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 329              payloadData + fragmentation->fragmentationOffset[0], | 328              payloadData + fragmentation->fragmentationOffset[0], | 
| 330              fragmentation->fragmentationLength[0]); | 329              fragmentation->fragmentationLength[0]); | 
| 331 | 330 | 
| 332       payloadSize = fragmentation->fragmentationLength[0]; | 331       payloadSize = fragmentation->fragmentationLength[0]; | 
| 333     } else { | 332     } else { | 
| 334       memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize); | 333       memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize); | 
| 335     } | 334     } | 
| 336   } | 335   } | 
| 337 | 336 | 
| 338   { | 337   { | 
| 339     CriticalSectionScoped cs(_sendAudioCritsect.get()); | 338     rtc::CritScope cs(&_sendAudioCritsect); | 
| 340     _lastPayloadType = payloadType; | 339     _lastPayloadType = payloadType; | 
| 341   } | 340   } | 
| 342   // Update audio level extension, if included. | 341   // Update audio level extension, if included. | 
| 343   size_t packetSize = payloadSize + rtpHeaderLength; | 342   size_t packetSize = payloadSize + rtpHeaderLength; | 
| 344   RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); | 343   RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); | 
| 345   RTPHeader rtp_header; | 344   RTPHeader rtp_header; | 
| 346   rtp_parser.Parse(&rtp_header); | 345   rtp_parser.Parse(&rtp_header); | 
| 347   _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header, | 346   _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header, | 
| 348                                (frameType == kAudioFrameSpeech), | 347                                (frameType == kAudioFrameSpeech), | 
| 349                                audio_level_dbov); | 348                                audio_level_dbov); | 
| 350   TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp", | 349   TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp", | 
| 351                          _rtpSender->Timestamp(), "seqnum", | 350                          _rtpSender->Timestamp(), "seqnum", | 
| 352                          _rtpSender->SequenceNumber()); | 351                          _rtpSender->SequenceNumber()); | 
| 353   int32_t send_result = _rtpSender->SendToNetwork( | 352   int32_t send_result = _rtpSender->SendToNetwork( | 
| 354       dataBuffer, payloadSize, rtpHeaderLength, | 353       dataBuffer, payloadSize, rtpHeaderLength, | 
| 355       TickTime::MillisecondTimestamp(), kAllowRetransmission, | 354       TickTime::MillisecondTimestamp(), kAllowRetransmission, | 
| 356       RtpPacketSender::kHighPriority); | 355       RtpPacketSender::kHighPriority); | 
| 357   if (first_packet_sent_()) { | 356   if (first_packet_sent_()) { | 
| 358     LOG(LS_INFO) << "First audio RTP packet sent to pacer"; | 357     LOG(LS_INFO) << "First audio RTP packet sent to pacer"; | 
| 359   } | 358   } | 
| 360   return send_result; | 359   return send_result; | 
| 361 } | 360 } | 
| 362 | 361 | 
| 363 // Audio level magnitude and voice activity flag are set for each RTP packet | 362 // Audio level magnitude and voice activity flag are set for each RTP packet | 
| 364 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) { | 363 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) { | 
| 365   if (level_dBov > 127) { | 364   if (level_dBov > 127) { | 
| 366     return -1; | 365     return -1; | 
| 367   } | 366   } | 
| 368   CriticalSectionScoped cs(_sendAudioCritsect.get()); | 367   rtc::CritScope cs(&_sendAudioCritsect); | 
| 369   _audioLevel_dBov = level_dBov; | 368   _audioLevel_dBov = level_dBov; | 
| 370   return 0; | 369   return 0; | 
| 371 } | 370 } | 
| 372 | 371 | 
| 373 // Set payload type for Redundant Audio Data RFC 2198 | 372 // Set payload type for Redundant Audio Data RFC 2198 | 
| 374 int32_t RTPSenderAudio::SetRED(int8_t payloadType) { | 373 int32_t RTPSenderAudio::SetRED(int8_t payloadType) { | 
| 375   if (payloadType < -1) { | 374   if (payloadType < -1) { | 
| 376     return -1; | 375     return -1; | 
| 377   } | 376   } | 
| 378   CriticalSectionScoped cs(_sendAudioCritsect.get()); | 377   rtc::CritScope cs(&_sendAudioCritsect); | 
| 379   _REDPayloadType = payloadType; | 378   _REDPayloadType = payloadType; | 
| 380   return 0; | 379   return 0; | 
| 381 } | 380 } | 
| 382 | 381 | 
| 383 // Get payload type for Redundant Audio Data RFC 2198 | 382 // Get payload type for Redundant Audio Data RFC 2198 | 
| 384 int32_t RTPSenderAudio::RED(int8_t* payloadType) const { | 383 int32_t RTPSenderAudio::RED(int8_t* payloadType) const { | 
| 385   CriticalSectionScoped cs(_sendAudioCritsect.get()); | 384   rtc::CritScope cs(&_sendAudioCritsect); | 
| 386   if (_REDPayloadType == -1) { | 385   if (_REDPayloadType == -1) { | 
| 387     // not configured | 386     // not configured | 
| 388     return -1; | 387     return -1; | 
| 389   } | 388   } | 
| 390   *payloadType = _REDPayloadType; | 389   *payloadType = _REDPayloadType; | 
| 391   return 0; | 390   return 0; | 
| 392 } | 391 } | 
| 393 | 392 | 
| 394 // Send a TelephoneEvent tone using RFC 2833 (4733) | 393 // Send a TelephoneEvent tone using RFC 2833 (4733) | 
| 395 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, | 394 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, | 
| 396                                            uint16_t time_ms, | 395                                            uint16_t time_ms, | 
| 397                                            uint8_t level) { | 396                                            uint8_t level) { | 
| 398   { | 397   { | 
| 399     CriticalSectionScoped lock(_sendAudioCritsect.get()); | 398     rtc::CritScope lock(&_sendAudioCritsect); | 
| 400     if (_dtmfPayloadType < 0) { | 399     if (_dtmfPayloadType < 0) { | 
| 401       // TelephoneEvent payloadtype not configured | 400       // TelephoneEvent payloadtype not configured | 
| 402       return -1; | 401       return -1; | 
| 403     } | 402     } | 
| 404   } | 403   } | 
| 405   return AddDTMF(key, time_ms, level); | 404   return AddDTMF(key, time_ms, level); | 
| 406 } | 405 } | 
| 407 | 406 | 
| 408 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended, | 407 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended, | 
| 409                                                  int8_t dtmf_payload_type, | 408                                                  int8_t dtmf_payload_type, | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 452                          dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber()); | 451                          dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber()); | 
| 453     retVal = _rtpSender->SendToNetwork( | 452     retVal = _rtpSender->SendToNetwork( | 
| 454         dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(), | 453         dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(), | 
| 455         kAllowRetransmission, RtpPacketSender::kHighPriority); | 454         kAllowRetransmission, RtpPacketSender::kHighPriority); | 
| 456     sendCount--; | 455     sendCount--; | 
| 457   } while (sendCount > 0 && retVal == 0); | 456   } while (sendCount > 0 && retVal == 0); | 
| 458 | 457 | 
| 459   return retVal; | 458   return retVal; | 
| 460 } | 459 } | 
| 461 }  // namespace webrtc | 460 }  // namespace webrtc | 
| OLD | NEW | 
|---|