blob: 4819e2dfef18874ccb43c7a8c757ca5d26e402c8 [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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "media/engine/webrtc_media_engine.h"
solenberg7e4e01a2015-12-02 08:05:01 -080012
13#include <algorithm>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
solenberg7e4e01a2015-12-02 08:05:01 -080015
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010016#include "absl/memory/memory.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080017#include "api/video/builtin_video_bitrate_allocator_factory.h"
Magnus Jedvert58b03162017-09-15 19:02:47 +020018#include "api/video_codecs/video_decoder_factory.h"
19#include "api/video_codecs/video_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "media/engine/webrtc_voice_engine.h"
kwiberg087bd342017-02-10 08:15:44 -080021
Anders Carlsson01092952018-12-11 15:44:54 +010022#if defined(USE_BUILTIN_SW_CODECS)
23#include "media/engine/convert_legacy_video_factory.h"
24#endif
25
jbauch4cb3e392016-01-26 13:07:54 -080026#ifdef HAVE_WEBRTC_VIDEO
Steve Anton10542f22019-01-11 09:11:00 -080027#include "media/engine/webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080028#else
Steve Anton10542f22019-01-11 09:11:00 -080029#include "media/engine/null_webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080030#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000031
32namespace cricket {
33
Anders Carlssondd8c1652018-01-30 10:32:13 +010034#if defined(USE_BUILTIN_SW_CODECS)
magjed2475ae22017-09-12 04:42:15 -070035namespace {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000036
magjed2475ae22017-09-12 04:42:15 -070037MediaEngineInterface* CreateWebRtcMediaEngine(
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000038 webrtc::AudioDeviceModule* adm,
ossueb1fde42017-05-02 06:46:30 -070039 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
40 audio_encoder_factory,
ossu29b1a8d2016-06-13 07:34:51 -070041 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
42 audio_decoder_factory,
magjed2475ae22017-09-12 04:42:15 -070043 WebRtcVideoEncoderFactory* video_encoder_factory,
44 WebRtcVideoDecoderFactory* video_decoder_factory,
Jiawei Ouc2ebe212018-11-08 10:02:56 -080045 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
46 video_bitrate_allocator_factory,
peaha9cc40b2017-06-29 08:32:09 -070047 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
48 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010049 std::unique_ptr<VideoEngineInterface> video_engine;
magjed2475ae22017-09-12 04:42:15 -070050#ifdef HAVE_WEBRTC_VIDEO
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010051 video_engine = absl::make_unique<WebRtcVideoEngine>(
Anders Carlsson01092952018-12-11 15:44:54 +010052 DEPRECATED_ConvertVideoEncoderFactory(
53 std::unique_ptr<WebRtcVideoEncoderFactory>(video_encoder_factory)),
54 DEPRECATED_ConvertVideoDecoderFactory(
55 std::unique_ptr<WebRtcVideoDecoderFactory>(video_decoder_factory)),
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010056 std::move(video_bitrate_allocator_factory));
magjed2475ae22017-09-12 04:42:15 -070057#else
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010058 video_engine = absl::make_unique<NullWebRtcVideoEngine>();
magjed2475ae22017-09-12 04:42:15 -070059#endif
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010060 return new CompositeMediaEngine(
61 absl::make_unique<WebRtcVoiceEngine>(adm, audio_encoder_factory,
62 audio_decoder_factory, audio_mixer,
63 audio_processing),
64 std::move(video_engine));
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000065}
66
magjed2475ae22017-09-12 04:42:15 -070067} // namespace
henrike@webrtc.org0481f152014-08-19 14:56:59 +000068
ossueb1fde42017-05-02 06:46:30 -070069MediaEngineInterface* WebRtcMediaEngineFactory::Create(
70 webrtc::AudioDeviceModule* adm,
71 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
72 audio_encoder_factory,
73 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
74 audio_decoder_factory,
75 WebRtcVideoEncoderFactory* video_encoder_factory,
Qingsi Wang59844ce2018-11-01 04:45:53 +000076 WebRtcVideoDecoderFactory* video_decoder_factory) {
Jiawei Ouc2ebe212018-11-08 10:02:56 -080077 return WebRtcMediaEngineFactory::Create(
78 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
79 video_decoder_factory,
80 webrtc::CreateBuiltinVideoBitrateAllocatorFactory());
81}
82
83MediaEngineInterface* WebRtcMediaEngineFactory::Create(
84 webrtc::AudioDeviceModule* adm,
85 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
86 audio_encoder_factory,
87 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
88 audio_decoder_factory,
89 WebRtcVideoEncoderFactory* video_encoder_factory,
90 WebRtcVideoDecoderFactory* video_decoder_factory,
91 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
92 video_bitrate_allocator_factory) {
93 return CreateWebRtcMediaEngine(
94 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
95 video_decoder_factory, std::move(video_bitrate_allocator_factory),
96 nullptr, webrtc::AudioProcessingBuilder().Create());
ossueb1fde42017-05-02 06:46:30 -070097}
98
99MediaEngineInterface* WebRtcMediaEngineFactory::Create(
100 webrtc::AudioDeviceModule* adm,
101 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
102 audio_encoder_factory,
103 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
104 audio_decoder_factory,
105 WebRtcVideoEncoderFactory* video_encoder_factory,
106 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700107 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
108 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800109 return WebRtcMediaEngineFactory::Create(
110 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
111 video_decoder_factory,
112 webrtc::CreateBuiltinVideoBitrateAllocatorFactory(), audio_mixer,
113 audio_processing);
114}
115
116MediaEngineInterface* WebRtcMediaEngineFactory::Create(
117 webrtc::AudioDeviceModule* adm,
118 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
119 audio_encoder_factory,
120 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
121 audio_decoder_factory,
122 WebRtcVideoEncoderFactory* video_encoder_factory,
123 WebRtcVideoDecoderFactory* video_decoder_factory,
124 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
125 video_bitrate_allocator_factory,
126 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
127 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
peaha9cc40b2017-06-29 08:32:09 -0700128 return CreateWebRtcMediaEngine(
129 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800130 video_decoder_factory, std::move(video_bitrate_allocator_factory),
131 audio_mixer, audio_processing);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000132}
Anders Carlssondd8c1652018-01-30 10:32:13 +0100133#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000134
Magnus Jedvert58b03162017-09-15 19:02:47 +0200135std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
136 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
137 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
138 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
139 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
140 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
141 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
142 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800143 return WebRtcMediaEngineFactory::Create(
144 adm, audio_encoder_factory, audio_decoder_factory,
145 std::move(video_encoder_factory), std::move(video_decoder_factory),
146 webrtc::CreateBuiltinVideoBitrateAllocatorFactory(), audio_mixer,
147 audio_processing);
148}
149
150std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
151 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
152 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
153 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
154 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
155 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
156 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
157 video_bitrate_allocator_factory,
158 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
159 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Magnus Jedvert58b03162017-09-15 19:02:47 +0200160#ifdef HAVE_WEBRTC_VIDEO
Sebastian Janssonfa0aa392018-11-16 09:54:32 +0100161 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
162 std::move(video_encoder_factory), std::move(video_decoder_factory),
163 std::move(video_bitrate_allocator_factory));
Magnus Jedvert58b03162017-09-15 19:02:47 +0200164#else
Sebastian Janssonfa0aa392018-11-16 09:54:32 +0100165 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
Magnus Jedvert58b03162017-09-15 19:02:47 +0200166#endif
Sebastian Janssonfa0aa392018-11-16 09:54:32 +0100167 return std::unique_ptr<MediaEngineInterface>(new CompositeMediaEngine(
168 absl::make_unique<WebRtcVoiceEngine>(adm, audio_encoder_factory,
169 audio_decoder_factory, audio_mixer,
170 audio_processing),
171 std::move(video_engine)));
Magnus Jedvert58b03162017-09-15 19:02:47 +0200172}
173
solenberg7e4e01a2015-12-02 08:05:01 -0800174namespace {
175// Remove mutually exclusive extensions with lower priority.
176void DiscardRedundantExtensions(
177 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700178 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800179 RTC_DCHECK(extensions);
180 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700181 for (const char* uri : extensions_decreasing_prio) {
182 auto it = std::find_if(
183 extensions->begin(), extensions->end(),
184 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800185 if (it != extensions->end()) {
186 if (found) {
187 extensions->erase(it);
188 }
189 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100190 }
191 }
solenberg7e4e01a2015-12-02 08:05:01 -0800192}
193} // namespace
194
isheriff6f8d6862016-05-26 11:24:55 -0700195bool ValidateRtpExtensions(
196 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200197 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -0800198 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200199 if (extension.id < webrtc::RtpExtension::kMinId ||
200 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100201 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800202 return false;
203 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200204 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100205 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
206 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800207 return false;
208 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200209 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -0800210 }
211 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100212}
213
solenberg7e4e01a2015-12-02 08:05:01 -0800214std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700215 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800216 bool (*supported)(const std::string&),
217 bool filter_redundant_extensions) {
218 RTC_DCHECK(ValidateRtpExtensions(extensions));
219 RTC_DCHECK(supported);
220 std::vector<webrtc::RtpExtension> result;
221
222 // Ignore any extensions that we don't recognize.
223 for (const auto& extension : extensions) {
224 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700225 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800226 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100227 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
228 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800229 }
230 }
231
jbauch5869f502017-06-29 12:31:36 -0700232 // Sort by name, ascending (prioritise encryption), so that we don't reset
233 // extensions if they were specified in a different order (also allows us
234 // to use std::unique below).
Yves Gerey665174f2018-06-19 15:03:05 +0200235 std::sort(
236 result.begin(), result.end(),
237 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
238 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
239 : rhs.encrypt > lhs.encrypt;
240 });
solenberg7e4e01a2015-12-02 08:05:01 -0800241
242 // Remove unnecessary extensions (used on send side).
243 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700244 auto it = std::unique(
245 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800246 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700247 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800248 });
249 result.erase(it, result.end());
250
251 // Keep just the highest priority extension of any in the following list.
agrieve26622d32017-08-08 10:48:15 -0700252 static const char* const kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700253 webrtc::RtpExtension::kTransportSequenceNumberUri,
254 webrtc::RtpExtension::kAbsSendTimeUri,
255 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800256 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
257 }
258
259 return result;
260}
stefan13f1a0a2016-11-30 07:22:58 -0800261
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100262webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
263 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800264 int bitrate_kbps = 0;
265 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
266 bitrate_kbps > 0) {
267 config.min_bitrate_bps = bitrate_kbps * 1000;
268 } else {
269 config.min_bitrate_bps = 0;
270 }
271 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
272 bitrate_kbps > 0) {
273 config.start_bitrate_bps = bitrate_kbps * 1000;
274 } else {
275 // Do not reconfigure start bitrate unless it's specified and positive.
276 config.start_bitrate_bps = -1;
277 }
278 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
279 bitrate_kbps > 0) {
280 config.max_bitrate_bps = bitrate_kbps * 1000;
281 } else {
282 config.max_bitrate_bps = -1;
283 }
284 return config;
285}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000286} // namespace cricket