1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11 #include "media/engine/webrtc_media_engine.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "absl/algorithm/container.h"
17 #include "media/engine/webrtc_voice_engine.h"
18 #include "system_wrappers/include/field_trial.h"
19
20 #ifdef HAVE_WEBRTC_VIDEO
21 #include "media/engine/webrtc_video_engine.h"
22 #else
23 #include "media/engine/null_webrtc_video_engine.h"
24 #endif
25
26 namespace cricket {
27
CreateMediaEngine(MediaEngineDependencies dependencies)28 std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
29 MediaEngineDependencies dependencies) {
30 auto audio_engine = std::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 = std::make_unique<WebRtcVideoEngine>(
38 std::move(dependencies.video_encoder_factory),
39 std::move(dependencies.video_decoder_factory));
40 #else
41 auto video_engine = std::make_unique<NullWebRtcVideoEngine>();
42 #endif
43 return std::make_unique<CompositeMediaEngine>(std::move(audio_engine),
44 std::move(video_engine));
45 }
46
47 namespace {
48 // Remove mutually exclusive extensions with lower priority.
DiscardRedundantExtensions(std::vector<webrtc::RtpExtension> * extensions,rtc::ArrayView<const char * const> extensions_decreasing_prio)49 void DiscardRedundantExtensions(
50 std::vector<webrtc::RtpExtension>* extensions,
51 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
52 RTC_DCHECK(extensions);
53 bool found = false;
54 for (const char* uri : extensions_decreasing_prio) {
55 auto it = absl::c_find_if(
56 *extensions,
57 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
58 if (it != extensions->end()) {
59 if (found) {
60 extensions->erase(it);
61 }
62 found = true;
63 }
64 }
65 }
66 } // namespace
67
ValidateRtpExtensions(const std::vector<webrtc::RtpExtension> & extensions)68 bool ValidateRtpExtensions(
69 const std::vector<webrtc::RtpExtension>& extensions) {
70 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
71 for (const auto& extension : extensions) {
72 if (extension.id < webrtc::RtpExtension::kMinId ||
73 extension.id > webrtc::RtpExtension::kMaxId) {
74 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
75 return false;
76 }
77 if (id_used[extension.id]) {
78 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
79 << extension.ToString();
80 return false;
81 }
82 id_used[extension.id] = true;
83 }
84 return true;
85 }
86
FilterRtpExtensions(const std::vector<webrtc::RtpExtension> & extensions,bool (* supported)(absl::string_view),bool filter_redundant_extensions)87 std::vector<webrtc::RtpExtension> FilterRtpExtensions(
88 const std::vector<webrtc::RtpExtension>& extensions,
89 bool (*supported)(absl::string_view),
90 bool filter_redundant_extensions) {
91 RTC_DCHECK(ValidateRtpExtensions(extensions));
92 RTC_DCHECK(supported);
93 std::vector<webrtc::RtpExtension> result;
94
95 // Ignore any extensions that we don't recognize.
96 for (const auto& extension : extensions) {
97 if (supported(extension.uri)) {
98 result.push_back(extension);
99 } else {
100 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
101 << extension.ToString();
102 }
103 }
104
105 // Sort by name, ascending (prioritise encryption), so that we don't reset
106 // extensions if they were specified in a different order (also allows us
107 // to use std::unique below).
108 absl::c_sort(result, [](const webrtc::RtpExtension& rhs,
109 const webrtc::RtpExtension& lhs) {
110 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
111 : rhs.encrypt > lhs.encrypt;
112 });
113
114 // Remove unnecessary extensions (used on send side).
115 if (filter_redundant_extensions) {
116 auto it = std::unique(
117 result.begin(), result.end(),
118 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
119 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
120 });
121 result.erase(it, result.end());
122
123 // Keep just the highest priority extension of any in the following lists.
124 if (webrtc::field_trial::IsEnabled("WebRTC-FilterAbsSendTimeExtension")) {
125 static const char* const kBweExtensionPriorities[] = {
126 webrtc::RtpExtension::kTransportSequenceNumberUri,
127 webrtc::RtpExtension::kAbsSendTimeUri,
128 webrtc::RtpExtension::kTimestampOffsetUri};
129 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
130 } else {
131 static const char* const kBweExtensionPriorities[] = {
132 webrtc::RtpExtension::kAbsSendTimeUri,
133 webrtc::RtpExtension::kTimestampOffsetUri};
134 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
135 }
136 }
137 return result;
138 }
139
GetBitrateConfigForCodec(const Codec & codec)140 webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
141 webrtc::BitrateConstraints config;
142 int bitrate_kbps = 0;
143 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
144 bitrate_kbps > 0) {
145 config.min_bitrate_bps = bitrate_kbps * 1000;
146 } else {
147 config.min_bitrate_bps = 0;
148 }
149 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
150 bitrate_kbps > 0) {
151 config.start_bitrate_bps = bitrate_kbps * 1000;
152 } else {
153 // Do not reconfigure start bitrate unless it's specified and positive.
154 config.start_bitrate_bps = -1;
155 }
156 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
157 bitrate_kbps > 0) {
158 config.max_bitrate_bps = bitrate_kbps * 1000;
159 } else {
160 config.max_bitrate_bps = -1;
161 }
162 return config;
163 }
164 } // namespace cricket
165