blob: 2a79c6b609a1cf534c89f86a6bc7e8267fb43ba0 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "media/engine/webrtcmediaengine.h"
solenberg7e4e01a2015-12-02 08:05:01 -080012
13#include <algorithm>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Magnus Jedvert58b03162017-09-15 19:02:47 +020017#include "api/video_codecs/video_decoder_factory.h"
18#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "media/engine/webrtcvoiceengine.h"
kwiberg087bd342017-02-10 08:15:44 -080020
jbauch4cb3e392016-01-26 13:07:54 -080021#ifdef HAVE_WEBRTC_VIDEO
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "media/engine/webrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080023#else
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080025#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000026
27namespace cricket {
28
magjed2475ae22017-09-12 04:42:15 -070029namespace {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000030
magjed2475ae22017-09-12 04:42:15 -070031MediaEngineInterface* CreateWebRtcMediaEngine(
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000032 webrtc::AudioDeviceModule* adm,
ossueb1fde42017-05-02 06:46:30 -070033 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
34 audio_encoder_factory,
ossu29b1a8d2016-06-13 07:34:51 -070035 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
36 audio_decoder_factory,
magjed2475ae22017-09-12 04:42:15 -070037 WebRtcVideoEncoderFactory* video_encoder_factory,
38 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070039 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
40 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
magjed2475ae22017-09-12 04:42:15 -070041#ifdef HAVE_WEBRTC_VIDEO
42 typedef WebRtcVideoEngine VideoEngine;
Magnus Jedvert02e7a192017-09-23 17:21:32 +020043 std::tuple<std::unique_ptr<WebRtcVideoEncoderFactory>,
44 std::unique_ptr<WebRtcVideoDecoderFactory>>
45 video_args(
46 (std::unique_ptr<WebRtcVideoEncoderFactory>(video_encoder_factory)),
47 (std::unique_ptr<WebRtcVideoDecoderFactory>(video_decoder_factory)));
magjed2475ae22017-09-12 04:42:15 -070048#else
49 typedef NullWebRtcVideoEngine VideoEngine;
50 std::tuple<> video_args;
51#endif
52 return new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
53 std::forward_as_tuple(adm, audio_encoder_factory, audio_decoder_factory,
54 audio_mixer, audio_processing),
55 std::move(video_args));
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000056}
57
magjed2475ae22017-09-12 04:42:15 -070058} // namespace
henrike@webrtc.org0481f152014-08-19 14:56:59 +000059
ossu111744e2016-06-15 02:22:32 -070060// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
61// audio decoder factory is fully plumbed and used throughout WebRTC.
62// See: crbug.com/webrtc/6000
63MediaEngineInterface* WebRtcMediaEngineFactory::Create(
64 webrtc::AudioDeviceModule* adm,
65 WebRtcVideoEncoderFactory* video_encoder_factory,
66 WebRtcVideoDecoderFactory* video_decoder_factory) {
gyzhou95aa9642016-12-13 14:06:26 -080067 return CreateWebRtcMediaEngine(
ossueb1fde42017-05-02 06:46:30 -070068 adm, webrtc::CreateBuiltinAudioEncoderFactory(),
69 webrtc::CreateBuiltinAudioDecoderFactory(), video_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070070 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
gyzhou95aa9642016-12-13 14:06:26 -080071}
72
73MediaEngineInterface* WebRtcMediaEngineFactory::Create(
74 webrtc::AudioDeviceModule* adm,
75 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
76 audio_decoder_factory,
77 WebRtcVideoEncoderFactory* video_encoder_factory,
78 WebRtcVideoDecoderFactory* video_decoder_factory) {
ossueb1fde42017-05-02 06:46:30 -070079 return CreateWebRtcMediaEngine(
80 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070081 video_encoder_factory, video_decoder_factory, nullptr,
82 webrtc::AudioProcessing::Create());
ossu111744e2016-06-15 02:22:32 -070083}
84
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000085// Used by PeerConnectionFactory to create a media engine passed into
86// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000087MediaEngineInterface* WebRtcMediaEngineFactory::Create(
88 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070089 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
90 audio_decoder_factory,
91 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080092 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070093 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
94 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
ossueb1fde42017-05-02 06:46:30 -070095 return CreateWebRtcMediaEngine(
96 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070097 video_encoder_factory, video_decoder_factory, audio_mixer,
98 audio_processing);
ossueb1fde42017-05-02 06:46:30 -070099}
100
101MediaEngineInterface* WebRtcMediaEngineFactory::Create(
102 webrtc::AudioDeviceModule* adm,
103 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
104 audio_encoder_factory,
105 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
106 audio_decoder_factory,
107 WebRtcVideoEncoderFactory* video_encoder_factory,
108 WebRtcVideoDecoderFactory* video_decoder_factory) {
peaha9cc40b2017-06-29 08:32:09 -0700109 return CreateWebRtcMediaEngine(
110 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
111 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
ossueb1fde42017-05-02 06:46:30 -0700112}
113
114MediaEngineInterface* WebRtcMediaEngineFactory::Create(
115 webrtc::AudioDeviceModule* adm,
116 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
117 audio_encoder_factory,
118 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
119 audio_decoder_factory,
120 WebRtcVideoEncoderFactory* video_encoder_factory,
121 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700122 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
123 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
124 return CreateWebRtcMediaEngine(
125 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
126 video_decoder_factory, audio_mixer, audio_processing);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000127}
128
Magnus Jedvert58b03162017-09-15 19:02:47 +0200129std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
130 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
131 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
132 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
133 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
134 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
135 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
136 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
137#ifdef HAVE_WEBRTC_VIDEO
138 typedef WebRtcVideoEngine VideoEngine;
139 std::tuple<std::unique_ptr<webrtc::VideoEncoderFactory>,
140 std::unique_ptr<webrtc::VideoDecoderFactory>>
141 video_args(std::move(video_encoder_factory),
142 std::move(video_decoder_factory));
143#else
144 typedef NullWebRtcVideoEngine VideoEngine;
145 std::tuple<> video_args;
146#endif
147 return std::unique_ptr<MediaEngineInterface>(
148 new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
149 std::forward_as_tuple(adm, audio_encoder_factory,
150 audio_decoder_factory, audio_mixer,
151 audio_processing),
152 std::move(video_args)));
153}
154
solenberg7e4e01a2015-12-02 08:05:01 -0800155namespace {
156// Remove mutually exclusive extensions with lower priority.
157void DiscardRedundantExtensions(
158 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700159 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800160 RTC_DCHECK(extensions);
161 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700162 for (const char* uri : extensions_decreasing_prio) {
163 auto it = std::find_if(
164 extensions->begin(), extensions->end(),
165 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800166 if (it != extensions->end()) {
167 if (found) {
168 extensions->erase(it);
169 }
170 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100171 }
172 }
solenberg7e4e01a2015-12-02 08:05:01 -0800173}
174} // namespace
175
isheriff6f8d6862016-05-26 11:24:55 -0700176bool ValidateRtpExtensions(
177 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800178 bool id_used[14] = {false};
179 for (const auto& extension : extensions) {
180 if (extension.id <= 0 || extension.id >= 15) {
181 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
182 return false;
183 }
184 if (id_used[extension.id - 1]) {
185 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
186 return false;
187 }
188 id_used[extension.id - 1] = true;
189 }
190 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100191}
192
solenberg7e4e01a2015-12-02 08:05:01 -0800193std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700194 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800195 bool (*supported)(const std::string&),
196 bool filter_redundant_extensions) {
197 RTC_DCHECK(ValidateRtpExtensions(extensions));
198 RTC_DCHECK(supported);
199 std::vector<webrtc::RtpExtension> result;
200
201 // Ignore any extensions that we don't recognize.
202 for (const auto& extension : extensions) {
203 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700204 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800205 } else {
206 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
207 }
208 }
209
jbauch5869f502017-06-29 12:31:36 -0700210 // Sort by name, ascending (prioritise encryption), so that we don't reset
211 // extensions if they were specified in a different order (also allows us
212 // to use std::unique below).
solenberg7e4e01a2015-12-02 08:05:01 -0800213 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700214 [](const webrtc::RtpExtension& rhs,
jbauch5869f502017-06-29 12:31:36 -0700215 const webrtc::RtpExtension& lhs) {
216 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
217 : rhs.encrypt > lhs.encrypt;
218 });
solenberg7e4e01a2015-12-02 08:05:01 -0800219
220 // Remove unnecessary extensions (used on send side).
221 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700222 auto it = std::unique(
223 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800224 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700225 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800226 });
227 result.erase(it, result.end());
228
229 // Keep just the highest priority extension of any in the following list.
agrieve26622d32017-08-08 10:48:15 -0700230 static const char* const kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700231 webrtc::RtpExtension::kTransportSequenceNumberUri,
232 webrtc::RtpExtension::kAbsSendTimeUri,
233 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800234 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
235 }
236
237 return result;
238}
stefan13f1a0a2016-11-30 07:22:58 -0800239
240webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec(
241 const Codec& codec) {
242 webrtc::Call::Config::BitrateConfig config;
243 int bitrate_kbps = 0;
244 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
245 bitrate_kbps > 0) {
246 config.min_bitrate_bps = bitrate_kbps * 1000;
247 } else {
248 config.min_bitrate_bps = 0;
249 }
250 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
251 bitrate_kbps > 0) {
252 config.start_bitrate_bps = bitrate_kbps * 1000;
253 } else {
254 // Do not reconfigure start bitrate unless it's specified and positive.
255 config.start_bitrate_bps = -1;
256 }
257 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
258 bitrate_kbps > 0) {
259 config.max_bitrate_bps = bitrate_kbps * 1000;
260 } else {
261 config.max_bitrate_bps = -1;
262 }
263 return config;
264}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000265} // namespace cricket