Index: webrtc/media/engine/webrtcvoiceengine.cc |
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc |
index 71803cbee38c845e1cf4afbfa90c15ca94f062e3..cf51cb7bf1b463704db5fd698d6291e3f2fc1c51 100644 |
--- a/webrtc/media/engine/webrtcvoiceengine.cc |
+++ b/webrtc/media/engine/webrtcvoiceengine.cc |
@@ -396,7 +396,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; |
} |
@@ -425,7 +425,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]; |
@@ -450,7 +450,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}, kOpusMaxBitrate}, |
{kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate}, |
{kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate}, |
@@ -462,6 +462,9 @@ const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[11] = { |
{kCnCodecName, 32000, 1, 106, false, {}}, |
{kCnCodecName, 16000, 1, 105, false, {}}, |
{kCnCodecName, 8000, 1, 13, false, {}}, |
+ {kDtmfCodecName, 48000, 1, 110, false, {}}, |
+ {kDtmfCodecName, 32000, 1, 112, false, {}}, |
+ {kDtmfCodecName, 16000, 1, 113, false, {}}, |
{kDtmfCodecName, 8000, 1, 126, false, {}} |
}; |
} // namespace { |
@@ -1090,10 +1093,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); |
@@ -1114,25 +1122,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; |
} |
@@ -1690,6 +1710,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."; |
@@ -1706,6 +1730,7 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
} |
if (playout_) { |
+ // TODO(solenberg): Remove this condition. Does it even apply? |
// Receive codecs can not be changed while playing. So we temporarily |
// pause playout. |
ChangePlayout(false); |