blob: 1a828393daff3d1946fbb5a6c1c60db1f56797d6 [file] [log] [blame]
pbos@webrtc.org289a35c2014-06-03 14:51:34 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.org289a35c2014-06-03 14:51:34 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
pbos@webrtc.org289a35c2014-06-03 14:51:34 +00009 */
10
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010011#include "webrtc/media/engine/webrtcmediaengine.h"
ossu111744e2016-06-15 02:22:32 -070012#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
solenberg7e4e01a2015-12-02 08:05:01 -080013
14#include <algorithm>
15
jbauch4cb3e392016-01-26 13:07:54 -080016#ifdef HAVE_WEBRTC_VIDEO
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010017#include "webrtc/media/engine/webrtcvideoengine2.h"
jbauch4cb3e392016-01-26 13:07:54 -080018#else
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010019#include "webrtc/media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080020#endif
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/webrtcvoiceengine.h"
henrike@webrtc.org0481f152014-08-19 14:56:59 +000022
23namespace cricket {
24
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000025class WebRtcMediaEngine2
jbauch4cb3e392016-01-26 13:07:54 -080026#ifdef HAVE_WEBRTC_VIDEO
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000027 : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
jbauch4cb3e392016-01-26 13:07:54 -080028#else
29 : public CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine> {
30#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000031 public:
32 WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070033 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
34 audio_decoder_factory,
35 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080036 WebRtcVideoDecoderFactory* video_decoder_factory,
37 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer)
solenbergff976312016-03-30 23:28:51 -070038#ifdef HAVE_WEBRTC_VIDEO
ossu29b1a8d2016-06-13 07:34:51 -070039 : CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2>(
gyzhou95aa9642016-12-13 14:06:26 -080040 adm,
41 audio_decoder_factory,
42 audio_mixer){
solenbergff976312016-03-30 23:28:51 -070043#else
ossu29b1a8d2016-06-13 07:34:51 -070044 : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
gyzhou95aa9642016-12-13 14:06:26 -080045 adm,
46 audio_decoder_factory,
47 audio_mixer) {
solenbergff976312016-03-30 23:28:51 -070048#endif
gyzhou95aa9642016-12-13 14:06:26 -080049 video_.SetExternalDecoderFactory(video_decoder_factory);
ossu29b1a8d2016-06-13 07:34:51 -070050 video_.SetExternalEncoderFactory(video_encoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000051 }
52};
henrike@webrtc.org0481f152014-08-19 14:56:59 +000053
54} // namespace cricket
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000055
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000056cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
57 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070058 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
59 audio_decoder_factory,
60 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080061 cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
62 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
63 return new cricket::WebRtcMediaEngine2(adm, audio_decoder_factory,
64 video_encoder_factory,
65 video_decoder_factory, audio_mixer);
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000066}
67
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000068void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000069 delete media_engine;
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000070}
henrike@webrtc.org0481f152014-08-19 14:56:59 +000071
72namespace cricket {
73
ossu111744e2016-06-15 02:22:32 -070074// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
75// audio decoder factory is fully plumbed and used throughout WebRTC.
76// See: crbug.com/webrtc/6000
77MediaEngineInterface* WebRtcMediaEngineFactory::Create(
78 webrtc::AudioDeviceModule* adm,
79 WebRtcVideoEncoderFactory* video_encoder_factory,
80 WebRtcVideoDecoderFactory* video_decoder_factory) {
gyzhou95aa9642016-12-13 14:06:26 -080081 return CreateWebRtcMediaEngine(
82 adm, webrtc::CreateBuiltinAudioDecoderFactory(), video_encoder_factory,
83 video_decoder_factory, nullptr);
84}
85
86MediaEngineInterface* WebRtcMediaEngineFactory::Create(
87 webrtc::AudioDeviceModule* adm,
88 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
89 audio_decoder_factory,
90 WebRtcVideoEncoderFactory* video_encoder_factory,
91 WebRtcVideoDecoderFactory* video_decoder_factory) {
92 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
93 video_encoder_factory, video_decoder_factory,
94 nullptr);
ossu111744e2016-06-15 02:22:32 -070095}
96
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000097// Used by PeerConnectionFactory to create a media engine passed into
98// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000099MediaEngineInterface* WebRtcMediaEngineFactory::Create(
100 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -0700101 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
102 audio_decoder_factory,
103 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -0800104 WebRtcVideoDecoderFactory* video_decoder_factory,
105 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
ossu29b1a8d2016-06-13 07:34:51 -0700106 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -0800107 video_encoder_factory, video_decoder_factory,
108 audio_mixer);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000109}
110
solenberg7e4e01a2015-12-02 08:05:01 -0800111namespace {
112// Remove mutually exclusive extensions with lower priority.
113void DiscardRedundantExtensions(
114 std::vector<webrtc::RtpExtension>* extensions,
115 rtc::ArrayView<const char*> extensions_decreasing_prio) {
116 RTC_DCHECK(extensions);
117 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700118 for (const char* uri : extensions_decreasing_prio) {
119 auto it = std::find_if(
120 extensions->begin(), extensions->end(),
121 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800122 if (it != extensions->end()) {
123 if (found) {
124 extensions->erase(it);
125 }
126 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100127 }
128 }
solenberg7e4e01a2015-12-02 08:05:01 -0800129}
130} // namespace
131
isheriff6f8d6862016-05-26 11:24:55 -0700132bool ValidateRtpExtensions(
133 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800134 bool id_used[14] = {false};
135 for (const auto& extension : extensions) {
136 if (extension.id <= 0 || extension.id >= 15) {
137 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
138 return false;
139 }
140 if (id_used[extension.id - 1]) {
141 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
142 return false;
143 }
144 id_used[extension.id - 1] = true;
145 }
146 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100147}
148
solenberg7e4e01a2015-12-02 08:05:01 -0800149std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700150 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800151 bool (*supported)(const std::string&),
152 bool filter_redundant_extensions) {
153 RTC_DCHECK(ValidateRtpExtensions(extensions));
154 RTC_DCHECK(supported);
155 std::vector<webrtc::RtpExtension> result;
156
157 // Ignore any extensions that we don't recognize.
158 for (const auto& extension : extensions) {
159 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700160 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800161 } else {
162 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
163 }
164 }
165
166 // Sort by name, ascending, so that we don't reset extensions if they were
167 // specified in a different order (also allows us to use std::unique below).
168 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700169 [](const webrtc::RtpExtension& rhs,
170 const webrtc::RtpExtension& lhs) { return rhs.uri < lhs.uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800171
172 // Remove unnecessary extensions (used on send side).
173 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700174 auto it = std::unique(
175 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800176 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
isheriff6f8d6862016-05-26 11:24:55 -0700177 return rhs.uri == lhs.uri;
solenberg7e4e01a2015-12-02 08:05:01 -0800178 });
179 result.erase(it, result.end());
180
181 // Keep just the highest priority extension of any in the following list.
182 static const char* kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700183 webrtc::RtpExtension::kTransportSequenceNumberUri,
184 webrtc::RtpExtension::kAbsSendTimeUri,
185 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800186 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
187 }
188
189 return result;
190}
stefan13f1a0a2016-11-30 07:22:58 -0800191
192webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec(
193 const Codec& codec) {
194 webrtc::Call::Config::BitrateConfig config;
195 int bitrate_kbps = 0;
196 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
197 bitrate_kbps > 0) {
198 config.min_bitrate_bps = bitrate_kbps * 1000;
199 } else {
200 config.min_bitrate_bps = 0;
201 }
202 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
203 bitrate_kbps > 0) {
204 config.start_bitrate_bps = bitrate_kbps * 1000;
205 } else {
206 // Do not reconfigure start bitrate unless it's specified and positive.
207 config.start_bitrate_bps = -1;
208 }
209 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
210 bitrate_kbps > 0) {
211 config.max_bitrate_bps = bitrate_kbps * 1000;
212 } else {
213 config.max_bitrate_bps = -1;
214 }
215 return config;
216}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000217} // namespace cricket