Index: webrtc/media/engine/webrtcvoiceengine.cc |
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc |
index 9f544c18262d13e812186b46e9a8f79277077bf3..53c8e6fd0dae2a0934b3b614fe087fcbd8fb8db2 100644 |
--- a/webrtc/media/engine/webrtcvoiceengine.cc |
+++ b/webrtc/media/engine/webrtcvoiceengine.cc |
@@ -424,7 +424,7 @@ class WebRtcVoiceCodecs final { |
// Select the preferred send codec (the first non-telephone-event/CN codec). |
for (const AudioCodec& codec : codecs) { |
if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { |
- // Skip telephone-event/CN codec, which will be handled later. |
+ // Skip telephone-event/CN codecs - they will be handled later. |
continue; |
} |
@@ -453,7 +453,7 @@ class WebRtcVoiceCodecs final { |
int max_bitrate_bps; |
}; |
// Note: keep the supported packet sizes in ascending order. |
- static const CodecPref kCodecPrefs[11]; |
+ static const CodecPref kCodecPrefs[14]; |
static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
@@ -478,7 +478,7 @@ class WebRtcVoiceCodecs final { |
} |
}; |
-const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[11] = { |
+const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[14] = { |
{kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrateBps}, |
{kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrateBps}, |
{kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrateBps}, |
@@ -490,7 +490,11 @@ const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[11] = { |
{kCnCodecName, 32000, 1, 106, false, {}}, |
{kCnCodecName, 16000, 1, 105, false, {}}, |
{kCnCodecName, 8000, 1, 13, false, {}}, |
- {kDtmfCodecName, 8000, 1, 126, false, {}}}; |
+ {kDtmfCodecName, 48000, 1, 110, false, {}}, |
+ {kDtmfCodecName, 32000, 1, 112, false, {}}, |
+ {kDtmfCodecName, 16000, 1, 113, false, {}}, |
+ {kDtmfCodecName, 8000, 1, 126, false, {}} |
+}; |
rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, |
int rtp_max_bitrate_bps, |
@@ -1124,10 +1128,15 @@ AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { |
const std::vector<webrtc::AudioCodecSpec>& specs = |
decoder_factory_->GetSupportedDecoders(); |
- // Only generate CN payload types for these clockrates |
+ // Only generate CN payload types for these clockrates: |
std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
{ 16000, false }, |
{ 32000, false }}; |
+ // Only generate telephone-event payload types for these clockrates: |
+ std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, |
+ { 16000, false }, |
+ { 32000, false }, |
+ { 48000, false }}; |
auto map_format = [&mapper, &out] (const webrtc::SdpAudioFormat& format) { |
rtc::Optional<AudioCodec> opt_codec = mapper.ToAudioCodec(format); |
@@ -1148,25 +1157,37 @@ AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { |
}; |
for (const auto& spec : specs) { |
- if (map_format(spec.format) && spec.allow_comfort_noise) { |
- // Generate a CN entry if the decoder allows it and we support the |
- // clockrate. |
- auto cn = generate_cn.find(spec.format.clockrate_hz); |
- if (cn != generate_cn.end()) { |
- cn->second = true; |
+ if (map_format(spec.format)) { |
+ if (spec.allow_comfort_noise) { |
+ // Generate a CN entry if the decoder allows it and we support the |
+ // clockrate. |
+ auto cn = generate_cn.find(spec.format.clockrate_hz); |
+ if (cn != generate_cn.end()) { |
+ cn->second = true; |
+ } |
+ } |
+ |
+ // Generate a telephone-event entry if we support the clockrate. |
+ auto dtmf = generate_dtmf.find(spec.format.clockrate_hz); |
+ if (dtmf != generate_dtmf.end()) { |
+ dtmf->second = true; |
} |
} |
} |
- // Add CN codecs after "proper" audio codecs |
+ // Add CN codecs after "proper" audio codecs. |
for (const auto& cn : generate_cn) { |
if (cn.second) { |
map_format({kCnCodecName, cn.first, 1}); |
} |
} |
- // Add telephone-event codec last |
- map_format({kDtmfCodecName, 8000, 1}); |
+ // Add telephone-event codecs last. |
+ for (const auto& dtmf : generate_dtmf) { |
+ if (dtmf.second) { |
+ map_format({kDtmfCodecName, dtmf.first, 1}); |
+ } |
+ } |
return out; |
} |
@@ -1794,6 +1815,10 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
// already be receiving packets with that payload type. |
for (const AudioCodec& codec : codecs) { |
AudioCodec old_codec; |
+ // TODO(solenberg): This isn't strictly correct. It should be possible to |
+ // add an additional payload type for a codec. That would result in a new |
+ // decoder object being allocated. What shouldn't work is to remove a PT |
+ // mapping that was previously configured. |
if (FindCodec(recv_codecs_, codec, &old_codec)) { |
if (old_codec.id != codec.id) { |
LOG(LS_ERROR) << codec.name << " payload type changed."; |