blob: b82b279277800899706a4711f72c9891e6a2ebb8 [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>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <memory>
15#include <tuple>
16#include <utility>
solenberg7e4e01a2015-12-02 08:05:01 -080017
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/audio_codecs/builtin_audio_decoder_factory.h"
19#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Magnus Jedvert58b03162017-09-15 19:02:47 +020020#include "api/video_codecs/video_decoder_factory.h"
21#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "media/engine/webrtcvoiceengine.h"
kwiberg087bd342017-02-10 08:15:44 -080023
jbauch4cb3e392016-01-26 13:07:54 -080024#ifdef HAVE_WEBRTC_VIDEO
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/webrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080026#else
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080028#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000029
30namespace cricket {
31
magjed2475ae22017-09-12 04:42:15 -070032namespace {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000033
magjed2475ae22017-09-12 04:42:15 -070034MediaEngineInterface* CreateWebRtcMediaEngine(
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000035 webrtc::AudioDeviceModule* adm,
ossueb1fde42017-05-02 06:46:30 -070036 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
37 audio_encoder_factory,
ossu29b1a8d2016-06-13 07:34:51 -070038 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
39 audio_decoder_factory,
magjed2475ae22017-09-12 04:42:15 -070040 WebRtcVideoEncoderFactory* video_encoder_factory,
41 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070042 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
43 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
magjed2475ae22017-09-12 04:42:15 -070044#ifdef HAVE_WEBRTC_VIDEO
45 typedef WebRtcVideoEngine VideoEngine;
Magnus Jedvert02e7a192017-09-23 17:21:32 +020046 std::tuple<std::unique_ptr<WebRtcVideoEncoderFactory>,
47 std::unique_ptr<WebRtcVideoDecoderFactory>>
48 video_args(
49 (std::unique_ptr<WebRtcVideoEncoderFactory>(video_encoder_factory)),
50 (std::unique_ptr<WebRtcVideoDecoderFactory>(video_decoder_factory)));
magjed2475ae22017-09-12 04:42:15 -070051#else
52 typedef NullWebRtcVideoEngine VideoEngine;
53 std::tuple<> video_args;
54#endif
55 return new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
56 std::forward_as_tuple(adm, audio_encoder_factory, audio_decoder_factory,
57 audio_mixer, audio_processing),
58 std::move(video_args));
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000059}
60
magjed2475ae22017-09-12 04:42:15 -070061} // namespace
henrike@webrtc.org0481f152014-08-19 14:56:59 +000062
ossu111744e2016-06-15 02:22:32 -070063// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
64// audio decoder factory is fully plumbed and used throughout WebRTC.
65// See: crbug.com/webrtc/6000
66MediaEngineInterface* WebRtcMediaEngineFactory::Create(
67 webrtc::AudioDeviceModule* adm,
68 WebRtcVideoEncoderFactory* video_encoder_factory,
69 WebRtcVideoDecoderFactory* video_decoder_factory) {
gyzhou95aa9642016-12-13 14:06:26 -080070 return CreateWebRtcMediaEngine(
ossueb1fde42017-05-02 06:46:30 -070071 adm, webrtc::CreateBuiltinAudioEncoderFactory(),
72 webrtc::CreateBuiltinAudioDecoderFactory(), video_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070073 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
gyzhou95aa9642016-12-13 14:06:26 -080074}
75
76MediaEngineInterface* WebRtcMediaEngineFactory::Create(
77 webrtc::AudioDeviceModule* adm,
78 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
79 audio_decoder_factory,
80 WebRtcVideoEncoderFactory* video_encoder_factory,
81 WebRtcVideoDecoderFactory* video_decoder_factory) {
ossueb1fde42017-05-02 06:46:30 -070082 return CreateWebRtcMediaEngine(
83 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070084 video_encoder_factory, video_decoder_factory, nullptr,
85 webrtc::AudioProcessing::Create());
ossu111744e2016-06-15 02:22:32 -070086}
87
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000088// Used by PeerConnectionFactory to create a media engine passed into
89// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000090MediaEngineInterface* WebRtcMediaEngineFactory::Create(
91 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070092 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
93 audio_decoder_factory,
94 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080095 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070096 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
97 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
ossueb1fde42017-05-02 06:46:30 -070098 return CreateWebRtcMediaEngine(
99 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700100 video_encoder_factory, video_decoder_factory, audio_mixer,
101 audio_processing);
ossueb1fde42017-05-02 06:46:30 -0700102}
103
104MediaEngineInterface* WebRtcMediaEngineFactory::Create(
105 webrtc::AudioDeviceModule* adm,
106 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
107 audio_encoder_factory,
108 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
109 audio_decoder_factory,
110 WebRtcVideoEncoderFactory* video_encoder_factory,
111 WebRtcVideoDecoderFactory* video_decoder_factory) {
peaha9cc40b2017-06-29 08:32:09 -0700112 return CreateWebRtcMediaEngine(
113 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
114 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
ossueb1fde42017-05-02 06:46:30 -0700115}
116
117MediaEngineInterface* WebRtcMediaEngineFactory::Create(
118 webrtc::AudioDeviceModule* adm,
119 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
120 audio_encoder_factory,
121 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
122 audio_decoder_factory,
123 WebRtcVideoEncoderFactory* video_encoder_factory,
124 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700125 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
126 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
127 return CreateWebRtcMediaEngine(
128 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
129 video_decoder_factory, audio_mixer, audio_processing);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000130}
131
Magnus Jedvert58b03162017-09-15 19:02:47 +0200132std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
133 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
134 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
135 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
136 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
137 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
138 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
139 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
140#ifdef HAVE_WEBRTC_VIDEO
141 typedef WebRtcVideoEngine VideoEngine;
142 std::tuple<std::unique_ptr<webrtc::VideoEncoderFactory>,
143 std::unique_ptr<webrtc::VideoDecoderFactory>>
144 video_args(std::move(video_encoder_factory),
145 std::move(video_decoder_factory));
146#else
147 typedef NullWebRtcVideoEngine VideoEngine;
148 std::tuple<> video_args;
149#endif
150 return std::unique_ptr<MediaEngineInterface>(
151 new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
152 std::forward_as_tuple(adm, audio_encoder_factory,
153 audio_decoder_factory, audio_mixer,
154 audio_processing),
155 std::move(video_args)));
156}
157
solenberg7e4e01a2015-12-02 08:05:01 -0800158namespace {
159// Remove mutually exclusive extensions with lower priority.
160void DiscardRedundantExtensions(
161 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700162 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800163 RTC_DCHECK(extensions);
164 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700165 for (const char* uri : extensions_decreasing_prio) {
166 auto it = std::find_if(
167 extensions->begin(), extensions->end(),
168 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800169 if (it != extensions->end()) {
170 if (found) {
171 extensions->erase(it);
172 }
173 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100174 }
175 }
solenberg7e4e01a2015-12-02 08:05:01 -0800176}
177} // namespace
178
isheriff6f8d6862016-05-26 11:24:55 -0700179bool ValidateRtpExtensions(
180 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800181 bool id_used[14] = {false};
182 for (const auto& extension : extensions) {
183 if (extension.id <= 0 || extension.id >= 15) {
184 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
185 return false;
186 }
187 if (id_used[extension.id - 1]) {
188 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
189 return false;
190 }
191 id_used[extension.id - 1] = true;
192 }
193 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100194}
195
solenberg7e4e01a2015-12-02 08:05:01 -0800196std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700197 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800198 bool (*supported)(const std::string&),
199 bool filter_redundant_extensions) {
200 RTC_DCHECK(ValidateRtpExtensions(extensions));
201 RTC_DCHECK(supported);
202 std::vector<webrtc::RtpExtension> result;
203
204 // Ignore any extensions that we don't recognize.
205 for (const auto& extension : extensions) {
206 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700207 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800208 } else {
209 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
210 }
211 }
212
jbauch5869f502017-06-29 12:31:36 -0700213 // Sort by name, ascending (prioritise encryption), so that we don't reset
214 // extensions if they were specified in a different order (also allows us
215 // to use std::unique below).
solenberg7e4e01a2015-12-02 08:05:01 -0800216 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700217 [](const webrtc::RtpExtension& rhs,
jbauch5869f502017-06-29 12:31:36 -0700218 const webrtc::RtpExtension& lhs) {
219 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
220 : rhs.encrypt > lhs.encrypt;
221 });
solenberg7e4e01a2015-12-02 08:05:01 -0800222
223 // Remove unnecessary extensions (used on send side).
224 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700225 auto it = std::unique(
226 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800227 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700228 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800229 });
230 result.erase(it, result.end());
231
232 // Keep just the highest priority extension of any in the following list.
agrieve26622d32017-08-08 10:48:15 -0700233 static const char* const kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700234 webrtc::RtpExtension::kTransportSequenceNumberUri,
235 webrtc::RtpExtension::kAbsSendTimeUri,
236 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800237 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
238 }
239
240 return result;
241}
stefan13f1a0a2016-11-30 07:22:58 -0800242
243webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec(
244 const Codec& codec) {
245 webrtc::Call::Config::BitrateConfig config;
246 int bitrate_kbps = 0;
247 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
248 bitrate_kbps > 0) {
249 config.min_bitrate_bps = bitrate_kbps * 1000;
250 } else {
251 config.min_bitrate_bps = 0;
252 }
253 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
254 bitrate_kbps > 0) {
255 config.start_bitrate_bps = bitrate_kbps * 1000;
256 } else {
257 // Do not reconfigure start bitrate unless it's specified and positive.
258 config.start_bitrate_bps = -1;
259 }
260 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
261 bitrate_kbps > 0) {
262 config.max_bitrate_bps = bitrate_kbps * 1000;
263 } else {
264 config.max_bitrate_bps = -1;
265 }
266 return config;
267}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000268} // namespace cricket