| 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.";
|
|
|