blob: 3b3875989f7bf187e90379bd90fa45c80825164e [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"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "media/engine/webrtc_voice_engine.h"
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010018#include "system_wrappers/include/field_trial.h"
kwiberg087bd342017-02-10 08:15:44 -080019
jbauch4cb3e392016-01-26 13:07:54 -080020#ifdef HAVE_WEBRTC_VIDEO
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/engine/webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080022#else
Steve Anton10542f22019-01-11 09:11:00 -080023#include "media/engine/null_webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080024#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000025
26namespace cricket {
27
Danil Chapovalov4844c5f2019-04-10 14:10:10 +020028std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
29 MediaEngineDependencies dependencies) {
30 auto audio_engine = absl::make_unique<WebRtcVoiceEngine>(
31 dependencies.task_queue_factory, std::move(dependencies.adm),
32 std::move(dependencies.audio_encoder_factory),
33 std::move(dependencies.audio_decoder_factory),
34 std::move(dependencies.audio_mixer),
35 std::move(dependencies.audio_processing));
36#ifdef HAVE_WEBRTC_VIDEO
37 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
38 std::move(dependencies.video_encoder_factory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +020039 std::move(dependencies.video_decoder_factory));
Danil Chapovalov4844c5f2019-04-10 14:10:10 +020040#else
41 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
42#endif
43 return absl::make_unique<CompositeMediaEngine>(std::move(audio_engine),
44 std::move(video_engine));
45}
46
solenberg7e4e01a2015-12-02 08:05:01 -080047namespace {
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010048// If this FieldTrial is enabled, we will not filter out the abs-send-time
49// header extension when the TWCC extensions were also negotiated, but keep
50// kAbsSendTimeUri also if kTransportSequenceNumberUri is present.
51bool IsKeepAbsSendTimeExtensionFieldTrialEnabled() {
52 return webrtc::field_trial::IsEnabled("WebRTC-KeepAbsSendTimeExtension");
53}
54
solenberg7e4e01a2015-12-02 08:05:01 -080055// Remove mutually exclusive extensions with lower priority.
56void DiscardRedundantExtensions(
57 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -070058 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -080059 RTC_DCHECK(extensions);
60 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -070061 for (const char* uri : extensions_decreasing_prio) {
Steve Anton2c9ebef2019-01-28 17:27:58 -080062 auto it = absl::c_find_if(
63 *extensions,
isheriff6f8d6862016-05-26 11:24:55 -070064 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -080065 if (it != extensions->end()) {
66 if (found) {
67 extensions->erase(it);
68 }
69 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010070 }
71 }
solenberg7e4e01a2015-12-02 08:05:01 -080072}
73} // namespace
74
isheriff6f8d6862016-05-26 11:24:55 -070075bool ValidateRtpExtensions(
76 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +020077 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -080078 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +020079 if (extension.id < webrtc::RtpExtension::kMinId ||
80 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010081 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -080082 return false;
83 }
Johannes Kron07ba2b92018-09-26 13:33:35 +020084 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010085 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
86 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -080087 return false;
88 }
Johannes Kron07ba2b92018-09-26 13:33:35 +020089 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -080090 }
91 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010092}
93
solenberg7e4e01a2015-12-02 08:05:01 -080094std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -070095 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -080096 bool (*supported)(const std::string&),
97 bool filter_redundant_extensions) {
98 RTC_DCHECK(ValidateRtpExtensions(extensions));
99 RTC_DCHECK(supported);
100 std::vector<webrtc::RtpExtension> result;
101
102 // Ignore any extensions that we don't recognize.
103 for (const auto& extension : extensions) {
104 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700105 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800106 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100107 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
108 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800109 }
110 }
111
jbauch5869f502017-06-29 12:31:36 -0700112 // Sort by name, ascending (prioritise encryption), so that we don't reset
113 // extensions if they were specified in a different order (also allows us
114 // to use std::unique below).
Jonas Olssona4d87372019-07-05 19:08:33 +0200115 absl::c_sort(result, [](const webrtc::RtpExtension& rhs,
116 const webrtc::RtpExtension& lhs) {
117 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
118 : rhs.encrypt > lhs.encrypt;
119 });
solenberg7e4e01a2015-12-02 08:05:01 -0800120
121 // Remove unnecessary extensions (used on send side).
122 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700123 auto it = std::unique(
124 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800125 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700126 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800127 });
128 result.erase(it, result.end());
129
Konrad Hofbauerb0397d62019-01-23 09:46:58 +0100130 // Keep just the highest priority extension of any in the following lists.
131 if (IsKeepAbsSendTimeExtensionFieldTrialEnabled()) {
132 static const char* const kBweExtensionPriorities[] = {
133 webrtc::RtpExtension::kAbsSendTimeUri,
134 webrtc::RtpExtension::kTimestampOffsetUri};
135 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
136 } else {
137 static const char* const kBweExtensionPriorities[] = {
138 webrtc::RtpExtension::kTransportSequenceNumberUri,
139 webrtc::RtpExtension::kAbsSendTimeUri,
140 webrtc::RtpExtension::kTimestampOffsetUri};
141 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
142 }
solenberg7e4e01a2015-12-02 08:05:01 -0800143 }
solenberg7e4e01a2015-12-02 08:05:01 -0800144 return result;
145}
stefan13f1a0a2016-11-30 07:22:58 -0800146
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100147webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
148 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800149 int bitrate_kbps = 0;
150 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
151 bitrate_kbps > 0) {
152 config.min_bitrate_bps = bitrate_kbps * 1000;
153 } else {
154 config.min_bitrate_bps = 0;
155 }
156 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
157 bitrate_kbps > 0) {
158 config.start_bitrate_bps = bitrate_kbps * 1000;
159 } else {
160 // Do not reconfigure start bitrate unless it's specified and positive.
161 config.start_bitrate_bps = -1;
162 }
163 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
164 bitrate_kbps > 0) {
165 config.max_bitrate_bps = bitrate_kbps * 1000;
166 } else {
167 config.max_bitrate_bps = -1;
168 }
169 return config;
170}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000171} // namespace cricket