blob: 5ea99b6e411c72536225d12e2cb176675707d921 [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"
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010021#include "system_wrappers/include/field_trial.h"
kwiberg087bd342017-02-10 08:15:44 -080022
jbauch4cb3e392016-01-26 13:07:54 -080023#ifdef HAVE_WEBRTC_VIDEO
Steve Anton10542f22019-01-11 09:11:00 -080024#include "media/engine/webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080025#else
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/engine/null_webrtc_video_engine.h"
jbauch4cb3e392016-01-26 13:07:54 -080027#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000028
29namespace cricket {
30
Magnus Jedvert58b03162017-09-15 19:02:47 +020031std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
32 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
33 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
34 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
35 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
36 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
37 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
38 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Jiawei Ouc2ebe212018-11-08 10:02:56 -080039 return WebRtcMediaEngineFactory::Create(
40 adm, audio_encoder_factory, audio_decoder_factory,
41 std::move(video_encoder_factory), std::move(video_decoder_factory),
42 webrtc::CreateBuiltinVideoBitrateAllocatorFactory(), audio_mixer,
43 audio_processing);
44}
45
46std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
47 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
48 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
49 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
50 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
51 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
52 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
53 video_bitrate_allocator_factory,
54 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
55 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
Magnus Jedvert58b03162017-09-15 19:02:47 +020056#ifdef HAVE_WEBRTC_VIDEO
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010057 auto video_engine = absl::make_unique<WebRtcVideoEngine>(
58 std::move(video_encoder_factory), std::move(video_decoder_factory),
59 std::move(video_bitrate_allocator_factory));
Magnus Jedvert58b03162017-09-15 19:02:47 +020060#else
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010061 auto video_engine = absl::make_unique<NullWebRtcVideoEngine>();
Magnus Jedvert58b03162017-09-15 19:02:47 +020062#endif
Sebastian Janssonfa0aa392018-11-16 09:54:32 +010063 return std::unique_ptr<MediaEngineInterface>(new CompositeMediaEngine(
64 absl::make_unique<WebRtcVoiceEngine>(adm, audio_encoder_factory,
65 audio_decoder_factory, audio_mixer,
66 audio_processing),
67 std::move(video_engine)));
Magnus Jedvert58b03162017-09-15 19:02:47 +020068}
69
solenberg7e4e01a2015-12-02 08:05:01 -080070namespace {
Konrad Hofbauerb0397d62019-01-23 09:46:58 +010071// If this FieldTrial is enabled, we will not filter out the abs-send-time
72// header extension when the TWCC extensions were also negotiated, but keep
73// kAbsSendTimeUri also if kTransportSequenceNumberUri is present.
74bool IsKeepAbsSendTimeExtensionFieldTrialEnabled() {
75 return webrtc::field_trial::IsEnabled("WebRTC-KeepAbsSendTimeExtension");
76}
77
solenberg7e4e01a2015-12-02 08:05:01 -080078// Remove mutually exclusive extensions with lower priority.
79void DiscardRedundantExtensions(
80 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -070081 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -080082 RTC_DCHECK(extensions);
83 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -070084 for (const char* uri : extensions_decreasing_prio) {
85 auto it = std::find_if(
86 extensions->begin(), extensions->end(),
87 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -080088 if (it != extensions->end()) {
89 if (found) {
90 extensions->erase(it);
91 }
92 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010093 }
94 }
solenberg7e4e01a2015-12-02 08:05:01 -080095}
96} // namespace
97
isheriff6f8d6862016-05-26 11:24:55 -070098bool ValidateRtpExtensions(
99 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200100 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -0800101 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200102 if (extension.id < webrtc::RtpExtension::kMinId ||
103 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100104 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800105 return false;
106 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200107 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100108 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
109 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800110 return false;
111 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200112 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -0800113 }
114 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100115}
116
solenberg7e4e01a2015-12-02 08:05:01 -0800117std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700118 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800119 bool (*supported)(const std::string&),
120 bool filter_redundant_extensions) {
121 RTC_DCHECK(ValidateRtpExtensions(extensions));
122 RTC_DCHECK(supported);
123 std::vector<webrtc::RtpExtension> result;
124
125 // Ignore any extensions that we don't recognize.
126 for (const auto& extension : extensions) {
127 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700128 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800129 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100130 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
131 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800132 }
133 }
134
jbauch5869f502017-06-29 12:31:36 -0700135 // Sort by name, ascending (prioritise encryption), so that we don't reset
136 // extensions if they were specified in a different order (also allows us
137 // to use std::unique below).
Yves Gerey665174f2018-06-19 15:03:05 +0200138 std::sort(
139 result.begin(), result.end(),
140 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
141 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
142 : rhs.encrypt > lhs.encrypt;
143 });
solenberg7e4e01a2015-12-02 08:05:01 -0800144
145 // Remove unnecessary extensions (used on send side).
146 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700147 auto it = std::unique(
148 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800149 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700150 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800151 });
152 result.erase(it, result.end());
153
Konrad Hofbauerb0397d62019-01-23 09:46:58 +0100154 // Keep just the highest priority extension of any in the following lists.
155 if (IsKeepAbsSendTimeExtensionFieldTrialEnabled()) {
156 static const char* const kBweExtensionPriorities[] = {
157 webrtc::RtpExtension::kAbsSendTimeUri,
158 webrtc::RtpExtension::kTimestampOffsetUri};
159 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
160 } else {
161 static const char* const kBweExtensionPriorities[] = {
162 webrtc::RtpExtension::kTransportSequenceNumberUri,
163 webrtc::RtpExtension::kAbsSendTimeUri,
164 webrtc::RtpExtension::kTimestampOffsetUri};
165 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
166 }
solenberg7e4e01a2015-12-02 08:05:01 -0800167 }
solenberg7e4e01a2015-12-02 08:05:01 -0800168 return result;
169}
stefan13f1a0a2016-11-30 07:22:58 -0800170
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100171webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
172 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800173 int bitrate_kbps = 0;
174 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
175 bitrate_kbps > 0) {
176 config.min_bitrate_bps = bitrate_kbps * 1000;
177 } else {
178 config.min_bitrate_bps = 0;
179 }
180 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
181 bitrate_kbps > 0) {
182 config.start_bitrate_bps = bitrate_kbps * 1000;
183 } else {
184 // Do not reconfigure start bitrate unless it's specified and positive.
185 config.start_bitrate_bps = -1;
186 }
187 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
188 bitrate_kbps > 0) {
189 config.max_bitrate_bps = bitrate_kbps * 1000;
190 } else {
191 config.max_bitrate_bps = -1;
192 }
193 return config;
194}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000195} // namespace cricket