blob: e2ead01979a16e93009a0d2c88d1940351aea825 [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"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080018#include "api/video/builtin_video_bitrate_allocator_factory.h"
Magnus Jedvert58b03162017-09-15 19:02:47 +020019#include "api/video_codecs/video_decoder_factory.h"
20#include "api/video_codecs/video_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/engine/webrtc_voice_engine.h"
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010022#include "system_wrappers/include/field_trial.h"
kwiberg087bd342017-02-10 08:15:44 -080023
jbauch4cb3e392016-01-26 13:07:54 -080024#ifdef HAVE_WEBRTC_VIDEO
Steve Anton10542f22019-01-11 09:11:00 -080025#include "media/engine/webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080026#else
Steve Anton10542f22019-01-11 09:11:00 -080027#include "media/engine/null_webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080028#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000029
30namespace cricket {
31
Danil Chapovalov4844c5f2019-04-10 14:10:10 +020032std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
33 MediaEngineDependencies dependencies) {
34 auto audio_engine = absl::make_unique<WebRtcVoiceEngine>(
35 dependencies.task_queue_factory, std::move(dependencies.adm),
36 std::move(dependencies.audio_encoder_factory),
37 std::move(dependencies.audio_decoder_factory),
38 std::move(dependencies.audio_mixer),
39 std::move(dependencies.audio_processing));
40#ifdef HAVE_WEBRTC_VIDEO
41 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
42 std::move(dependencies.video_encoder_factory),
43 std::move(dependencies.video_decoder_factory),
44 std::move(dependencies.video_bitrate_allocator_factory));
45#else
46 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
47#endif
48 return absl::make_unique<CompositeMediaEngine>(std::move(audio_engine),
49 std::move(video_engine));
50}
51
Magnus Jedvert58b03162017-09-15 19:02:47 +020052std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
53 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
54 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
55 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
56 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
57 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
58 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
59 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Jiawei Ouc2ebe212018-11-08 10:02:56 -080060 return WebRtcMediaEngineFactory::Create(
61 adm, audio_encoder_factory, audio_decoder_factory,
62 std::move(video_encoder_factory), std::move(video_decoder_factory),
63 webrtc::CreateBuiltinVideoBitrateAllocatorFactory(), audio_mixer,
64 audio_processing);
65}
66
67std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
68 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
69 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
70 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
71 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
72 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
73 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
74 video_bitrate_allocator_factory,
75 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
76 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Magnus Jedvert58b03162017-09-15 19:02:47 +020077#ifdef HAVE_WEBRTC_VIDEO
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010078 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
79 std::move(video_encoder_factory), std::move(video_decoder_factory),
80 std::move(video_bitrate_allocator_factory));
Magnus Jedvert58b03162017-09-15 19:02:47 +020081#else
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010082 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
Magnus Jedvert58b03162017-09-15 19:02:47 +020083#endif
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010084 return std::unique_ptr<MediaEngineInterface>(new CompositeMediaEngine(
Danil Chapovalov4c7112a2019-03-27 18:51:45 +010085 absl::make_unique<WebRtcVoiceEngine>(
86 &webrtc::GlobalTaskQueueFactory(), adm, audio_encoder_factory,
87 audio_decoder_factory, audio_mixer, audio_processing),
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010088 std::move(video_engine)));
Magnus Jedvert58b03162017-09-15 19:02:47 +020089}
90
solenberg7e4e01a2015-12-02 08:05:01 -080091namespace {
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010092// If this FieldTrial is enabled, we will not filter out the abs-send-time
93// header extension when the TWCC extensions were also negotiated, but keep
94// kAbsSendTimeUri also if kTransportSequenceNumberUri is present.
95bool IsKeepAbsSendTimeExtensionFieldTrialEnabled() {
96 return webrtc::field_trial::IsEnabled("WebRTC-KeepAbsSendTimeExtension");
97}
98
solenberg7e4e01a2015-12-02 08:05:01 -080099// Remove mutually exclusive extensions with lower priority.
100void DiscardRedundantExtensions(
101 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700102 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800103 RTC_DCHECK(extensions);
104 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700105 for (const char* uri : extensions_decreasing_prio) {
Steve Anton2c9ebef2019-01-28 17:27:58 -0800106 auto it = absl::c_find_if(
107 *extensions,
isheriff6f8d6862016-05-26 11:24:55 -0700108 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800109 if (it != extensions->end()) {
110 if (found) {
111 extensions->erase(it);
112 }
113 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100114 }
115 }
solenberg7e4e01a2015-12-02 08:05:01 -0800116}
117} // namespace
118
isheriff6f8d6862016-05-26 11:24:55 -0700119bool ValidateRtpExtensions(
120 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200121 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -0800122 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200123 if (extension.id < webrtc::RtpExtension::kMinId ||
124 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100125 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800126 return false;
127 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200128 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100129 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
130 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800131 return false;
132 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200133 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -0800134 }
135 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100136}
137
solenberg7e4e01a2015-12-02 08:05:01 -0800138std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700139 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800140 bool (*supported)(const std::string&),
141 bool filter_redundant_extensions) {
142 RTC_DCHECK(ValidateRtpExtensions(extensions));
143 RTC_DCHECK(supported);
144 std::vector<webrtc::RtpExtension> result;
145
146 // Ignore any extensions that we don't recognize.
147 for (const auto& extension : extensions) {
148 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700149 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800150 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100151 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
152 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800153 }
154 }
155
jbauch5869f502017-06-29 12:31:36 -0700156 // Sort by name, ascending (prioritise encryption), so that we don't reset
157 // extensions if they were specified in a different order (also allows us
158 // to use std::unique below).
Steve Anton2c9ebef2019-01-28 17:27:58 -0800159 absl::c_sort(
160 result,
Yves Gerey665174f2018-06-19 15:03:05 +0200161 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
162 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
163 : rhs.encrypt > lhs.encrypt;
164 });
solenberg7e4e01a2015-12-02 08:05:01 -0800165
166 // Remove unnecessary extensions (used on send side).
167 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700168 auto it = std::unique(
169 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800170 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700171 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800172 });
173 result.erase(it, result.end());
174
Konrad Hofbauerb0397d62019-01-23 09:46:58 +0100175 // Keep just the highest priority extension of any in the following lists.
176 if (IsKeepAbsSendTimeExtensionFieldTrialEnabled()) {
177 static const char* const kBweExtensionPriorities[] = {
178 webrtc::RtpExtension::kAbsSendTimeUri,
179 webrtc::RtpExtension::kTimestampOffsetUri};
180 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
181 } else {
182 static const char* const kBweExtensionPriorities[] = {
183 webrtc::RtpExtension::kTransportSequenceNumberUri,
184 webrtc::RtpExtension::kAbsSendTimeUri,
185 webrtc::RtpExtension::kTimestampOffsetUri};
186 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
187 }
solenberg7e4e01a2015-12-02 08:05:01 -0800188 }
solenberg7e4e01a2015-12-02 08:05:01 -0800189 return result;
190}
stefan13f1a0a2016-11-30 07:22:58 -0800191
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100192webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
193 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800194 int bitrate_kbps = 0;
195 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
196 bitrate_kbps > 0) {
197 config.min_bitrate_bps = bitrate_kbps * 1000;
198 } else {
199 config.min_bitrate_bps = 0;
200 }
201 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
202 bitrate_kbps > 0) {
203 config.start_bitrate_bps = bitrate_kbps * 1000;
204 } else {
205 // Do not reconfigure start bitrate unless it's specified and positive.
206 config.start_bitrate_bps = -1;
207 }
208 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
209 bitrate_kbps > 0) {
210 config.max_bitrate_bps = bitrate_kbps * 1000;
211 } else {
212 config.max_bitrate_bps = -1;
213 }
214 return config;
215}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000216} // namespace cricket