| Index: talk/media/webrtc/webrtcvoiceengine.cc
|
| diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
|
| index d1f76ef4b24f71ba9b9e53bf6bf0bd86d0ddd66a..d70c86495dc58841656e2c479b5b66a0709d32a4 100644
|
| --- a/talk/media/webrtc/webrtcvoiceengine.cc
|
| +++ b/talk/media/webrtc/webrtcvoiceengine.cc
|
| @@ -134,6 +134,12 @@ const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump";
|
| const char kAecDumpByAudioOptionFilename[] = "audio.aecdump";
|
| #endif
|
|
|
| +// Constants from voice_engine_defines.h.
|
| +const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1)
|
| +const int kMaxTelephoneEventCode = 255;
|
| +const int kMinTelephoneEventDuration = 100;
|
| +const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16
|
| +
|
| bool ValidateStreamParams(const StreamParams& sp) {
|
| if (sp.ssrcs.empty()) {
|
| LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString();
|
| @@ -582,12 +588,6 @@ bool WebRtcVoiceEngine::InitInternal() {
|
| LOG(LS_INFO) << ToString(codec);
|
| }
|
|
|
| - // Disable the DTMF playout when a tone is sent.
|
| - // PlayDtmfTone will be used if local playout is needed.
|
| - if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) {
|
| - LOG_RTCERR1(SetDtmfFeedbackStatus, false);
|
| - }
|
| -
|
| initialized_ = true;
|
| return true;
|
| }
|
| @@ -1258,6 +1258,13 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
|
| RTC_CHECK(stream_);
|
| }
|
|
|
| + bool SendTelephoneEvent(int payload_type, uint8_t event,
|
| + uint32_t duration_ms) {
|
| + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| + RTC_DCHECK(stream_);
|
| + return stream_->SendTelephoneEvent(payload_type, event, duration_ms);
|
| + }
|
| +
|
| webrtc::AudioSendStream::Stats GetStats() const {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| RTC_DCHECK(stream_);
|
| @@ -1612,7 +1619,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
|
| engine()->voe()->codec()->SetFECStatus(channel, false);
|
|
|
| // Scan through the list to figure out the codec to use for sending, along
|
| - // with the proper configuration for VAD and DTMF.
|
| + // with the proper configuration for VAD.
|
| bool found_send_codec = false;
|
| webrtc::CodecInst send_codec;
|
| memset(&send_codec, 0, sizeof(send_codec));
|
| @@ -1741,7 +1748,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
|
| SetSendBitrateInternal(send_bitrate_bps_);
|
| }
|
|
|
| - // Loop through the codecs list again to config the telephone-event/CN codec.
|
| + // Loop through the codecs list again to config the CN codec.
|
| for (const AudioCodec& codec : codecs) {
|
| // Ignore codecs we don't know about. The negotiation step should prevent
|
| // this, but double-check to be sure.
|
| @@ -1751,15 +1758,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
|
| continue;
|
| }
|
|
|
| - // Find the DTMF telephone event "codec" and tell VoiceEngine channels
|
| - // about it.
|
| - if (IsCodec(codec, kDtmfCodecName)) {
|
| - if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType(
|
| - channel, codec.id) == -1) {
|
| - LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, codec.id);
|
| - return false;
|
| - }
|
| - } else if (IsCodec(codec, kCnCodecName)) {
|
| + if (IsCodec(codec, kCnCodecName)) {
|
| // Turn voice activity detection/comfort noise on if supported.
|
| // Set the wideband CN payload type appropriately.
|
| // (narrowband always uses the static payload type 13).
|
| @@ -1814,12 +1813,16 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
|
| bool WebRtcVoiceMediaChannel::SetSendCodecs(
|
| const std::vector<AudioCodec>& codecs) {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| + // TODO(solenberg): Validate input - that payload types don't overlap, are
|
| + // within range, filter out codecs we don't support,
|
| + // redundant codecs etc.
|
|
|
| - dtmf_allowed_ = false;
|
| + // Find the DTMF telephone event "codec" payload type.
|
| + dtmf_payload_type_ = rtc::Optional<int>();
|
| for (const AudioCodec& codec : codecs) {
|
| - // Find the DTMF telephone event "codec".
|
| if (IsCodec(codec, kDtmfCodecName)) {
|
| - dtmf_allowed_ = true;
|
| + dtmf_payload_type_ = rtc::Optional<int>(codec.id);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -2282,38 +2285,34 @@ bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) {
|
| }
|
|
|
| bool WebRtcVoiceMediaChannel::CanInsertDtmf() {
|
| - return dtmf_allowed_;
|
| + return dtmf_payload_type_ ? true : false;
|
| }
|
|
|
| bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event,
|
| int duration) {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| - if (!dtmf_allowed_) {
|
| + LOG(LS_INFO) << "WebRtcVoiceMediaChannel::InsertDtmf";
|
| + if (!dtmf_payload_type_) {
|
| return false;
|
| }
|
|
|
| - // Send the event.
|
| - int channel = -1;
|
| - if (ssrc == 0) {
|
| - if (send_streams_.size() > 0) {
|
| - channel = send_streams_.begin()->second->channel();
|
| - }
|
| - } else {
|
| - channel = GetSendChannelId(ssrc);
|
| + // Figure out which WebRtcAudioSendStream to send the event on.
|
| + auto it = ssrc != 0 ? send_streams_.find(ssrc) : send_streams_.begin();
|
| + if (it == send_streams_.end()) {
|
| + LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use.";
|
| + return false;
|
| }
|
| - if (channel == -1) {
|
| - LOG(LS_WARNING) << "InsertDtmf - The specified ssrc "
|
| - << ssrc << " is not in use.";
|
| + if (event < kMinTelephoneEventCode ||
|
| + event > kMaxTelephoneEventCode) {
|
| + LOG(LS_WARNING) << "DTMF event code " << event << " out of range.";
|
| return false;
|
| }
|
| - // Send DTMF using out-of-band DTMF. ("true", as 3rd arg)
|
| - if (engine()->voe()->dtmf()->SendTelephoneEvent(
|
| - channel, event, true, duration) == -1) {
|
| - LOG_RTCERR4(SendTelephoneEvent, channel, event, true, duration);
|
| + if (duration < kMinTelephoneEventDuration ||
|
| + duration > kMaxTelephoneEventDuration) {
|
| + LOG(LS_WARNING) << "DTMF event duration " << duration << " out of range.";
|
| return false;
|
| }
|
| -
|
| - return true;
|
| + return it->second->SendTelephoneEvent(*dtmf_payload_type_, event, duration);
|
| }
|
|
|
| void WebRtcVoiceMediaChannel::OnPacketReceived(
|
|
|