blob: 480d090157e4df6205babc340e45eb2c3398da01 [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
Steve Antone78bcb92017-10-31 09:53:08 -070013#include <utility>
solenberg7e4e01a2015-12-02 08:05:01 -080014
Steve Anton2c9ebef2019-01-28 17:27:58 -080015#include "absl/algorithm/container.h"
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010016#include "absl/memory/memory.h"
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010017#include "api/task_queue/global_task_queue_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "media/engine/webrtc_voice_engine.h"
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010019#include "system_wrappers/include/field_trial.h"
kwiberg087bd342017-02-10 08:15:44 -080020
jbauch4cb3e392016-01-26 13:07:54 -080021#ifdef HAVE_WEBRTC_VIDEO
Steve Anton10542f22019-01-11 09:11:00 -080022#include "media/engine/webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080023#else
Steve Anton10542f22019-01-11 09:11:00 -080024#include "media/engine/null_webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080025#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000026
27namespace cricket {
28
Danil Chapovalov4844c5f2019-04-10 14:10:10 +020029std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
30 MediaEngineDependencies dependencies) {
31 auto audio_engine = absl::make_unique<WebRtcVoiceEngine>(
32 dependencies.task_queue_factory, std::move(dependencies.adm),
33 std::move(dependencies.audio_encoder_factory),
34 std::move(dependencies.audio_decoder_factory),
35 std::move(dependencies.audio_mixer),
36 std::move(dependencies.audio_processing));
37#ifdef HAVE_WEBRTC_VIDEO
38 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
39 std::move(dependencies.video_encoder_factory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +020040 std::move(dependencies.video_decoder_factory));
Danil Chapovalov4844c5f2019-04-10 14:10:10 +020041#else
42 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
43#endif
44 return absl::make_unique<CompositeMediaEngine>(std::move(audio_engine),
45 std::move(video_engine));
46}
47
Magnus Jedvert58b03162017-09-15 19:02:47 +020048std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
49 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
50 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
51 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
52 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
53 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
54 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
55 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
56#ifdef HAVE_WEBRTC_VIDEO
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010057 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +020058 std::move(video_encoder_factory), std::move(video_decoder_factory));
Magnus Jedvert58b03162017-09-15 19:02:47 +020059#else
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010060 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
Magnus Jedvert58b03162017-09-15 19:02:47 +020061#endif
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010062 return std::unique_ptr<MediaEngineInterface>(new CompositeMediaEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010063 absl::make_unique<WebRtcVoiceEngine>(
64 &webrtc::GlobalTaskQueueFactory(), adm, audio_encoder_factory,
65 audio_decoder_factory, audio_mixer, audio_processing),
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010066 std::move(video_engine)));
Magnus Jedvert58b03162017-09-15 19:02:47 +020067}
68
solenberg7e4e01a2015-12-02 08:05:01 -080069namespace {
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010070// If this FieldTrial is enabled, we will not filter out the abs-send-time
71// header extension when the TWCC extensions were also negotiated, but keep
72// kAbsSendTimeUri also if kTransportSequenceNumberUri is present.
73bool IsKeepAbsSendTimeExtensionFieldTrialEnabled() {
74 return webrtc::field_trial::IsEnabled("WebRTC-KeepAbsSendTimeExtension");
75}
76
solenberg7e4e01a2015-12-02 08:05:01 -080077// Remove mutually exclusive extensions with lower priority.
78void DiscardRedundantExtensions(
79 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -070080 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -080081 RTC_DCHECK(extensions);
82 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -070083 for (const char* uri : extensions_decreasing_prio) {
Steve Anton2c9ebef2019-01-28 17:27:58 -080084 auto it = absl::c_find_if(
85 *extensions,
isheriff6f8d6862016-05-26 11:24:55 -070086 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -080087 if (it != extensions->end()) {
88 if (found) {
89 extensions->erase(it);
90 }
91 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010092 }
93 }
solenberg7e4e01a2015-12-02 08:05:01 -080094}
95} // namespace
96
isheriff6f8d6862016-05-26 11:24:55 -070097bool ValidateRtpExtensions(
98 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +020099 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -0800100 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200101 if (extension.id < webrtc::RtpExtension::kMinId ||
102 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100103 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800104 return false;
105 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200106 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100107 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
108 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800109 return false;
110 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200111 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -0800112 }
113 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100114}
115
solenberg7e4e01a2015-12-02 08:05:01 -0800116std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700117 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800118 bool (*supported)(const std::string&),
119 bool filter_redundant_extensions) {
120 RTC_DCHECK(ValidateRtpExtensions(extensions));
121 RTC_DCHECK(supported);
122 std::vector<webrtc::RtpExtension> result;
123
124 // Ignore any extensions that we don't recognize.
125 for (const auto& extension : extensions) {
126 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700127 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800128 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100129 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
130 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800131 }
132 }
133
jbauch5869f502017-06-29 12:31:36 -0700134 // Sort by name, ascending (prioritise encryption), so that we don't reset
135 // extensions if they were specified in a different order (also allows us
136 // to use std::unique below).
Jonas Olssona4d87372019-07-05 19:08:33 +0200137 absl::c_sort(result, [](const webrtc::RtpExtension& rhs,
138 const webrtc::RtpExtension& lhs) {
139 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
140 : rhs.encrypt > lhs.encrypt;
141 });
solenberg7e4e01a2015-12-02 08:05:01 -0800142
143 // Remove unnecessary extensions (used on send side).
144 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700145 auto it = std::unique(
146 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800147 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700148 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800149 });
150 result.erase(it, result.end());
151
Konrad Hofbauerb0397d62019-01-23 09:46:58 +0100152 // Keep just the highest priority extension of any in the following lists.
153 if (IsKeepAbsSendTimeExtensionFieldTrialEnabled()) {
154 static const char* const kBweExtensionPriorities[] = {
155 webrtc::RtpExtension::kAbsSendTimeUri,
156 webrtc::RtpExtension::kTimestampOffsetUri};
157 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
158 } else {
159 static const char* const kBweExtensionPriorities[] = {
160 webrtc::RtpExtension::kTransportSequenceNumberUri,
161 webrtc::RtpExtension::kAbsSendTimeUri,
162 webrtc::RtpExtension::kTimestampOffsetUri};
163 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
164 }
solenberg7e4e01a2015-12-02 08:05:01 -0800165 }
solenberg7e4e01a2015-12-02 08:05:01 -0800166 return result;
167}
stefan13f1a0a2016-11-30 07:22:58 -0800168
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100169webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
170 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800171 int bitrate_kbps = 0;
172 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
173 bitrate_kbps > 0) {
174 config.min_bitrate_bps = bitrate_kbps * 1000;
175 } else {
176 config.min_bitrate_bps = 0;
177 }
178 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
179 bitrate_kbps > 0) {
180 config.start_bitrate_bps = bitrate_kbps * 1000;
181 } else {
182 // Do not reconfigure start bitrate unless it's specified and positive.
183 config.start_bitrate_bps = -1;
184 }
185 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
186 bitrate_kbps > 0) {
187 config.max_bitrate_bps = bitrate_kbps * 1000;
188 } else {
189 config.max_bitrate_bps = -1;
190 }
191 return config;
192}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000193} // namespace cricket