blob: 3a61ad73bb6c9057970052d6dfa6917b5bd0aa44 [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
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010011#include "webrtc/media/engine/webrtcmediaengine.h"
solenberg7e4e01a2015-12-02 08:05:01 -080012
13#include <algorithm>
14
kwiberg087bd342017-02-10 08:15:44 -080015#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070016#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
kwiberg087bd342017-02-10 08:15:44 -080017#include "webrtc/media/engine/webrtcvoiceengine.h"
18
jbauch4cb3e392016-01-26 13:07:54 -080019#ifdef HAVE_WEBRTC_VIDEO
eladalonf1841382017-06-12 01:16:46 -070020#include "webrtc/media/engine/webrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080021#else
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010022#include "webrtc/media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080023#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000024
25namespace cricket {
26
magjed2475ae22017-09-12 04:42:15 -070027namespace {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000028
magjed2475ae22017-09-12 04:42:15 -070029MediaEngineInterface* CreateWebRtcMediaEngine(
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000030 webrtc::AudioDeviceModule* adm,
ossueb1fde42017-05-02 06:46:30 -070031 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
32 audio_encoder_factory,
ossu29b1a8d2016-06-13 07:34:51 -070033 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
34 audio_decoder_factory,
magjed2475ae22017-09-12 04:42:15 -070035 WebRtcVideoEncoderFactory* video_encoder_factory,
36 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070037 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
38 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
magjed2475ae22017-09-12 04:42:15 -070039#ifdef HAVE_WEBRTC_VIDEO
40 typedef WebRtcVideoEngine VideoEngine;
41 std::tuple<WebRtcVideoEncoderFactory*, WebRtcVideoDecoderFactory*> video_args(
42 video_encoder_factory, video_decoder_factory);
43#else
44 typedef NullWebRtcVideoEngine VideoEngine;
45 std::tuple<> video_args;
46#endif
47 return new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
48 std::forward_as_tuple(adm, audio_encoder_factory, audio_decoder_factory,
49 audio_mixer, audio_processing),
50 std::move(video_args));
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000051}
52
magjed2475ae22017-09-12 04:42:15 -070053} // namespace
henrike@webrtc.org0481f152014-08-19 14:56:59 +000054
ossu111744e2016-06-15 02:22:32 -070055// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
56// audio decoder factory is fully plumbed and used throughout WebRTC.
57// See: crbug.com/webrtc/6000
58MediaEngineInterface* WebRtcMediaEngineFactory::Create(
59 webrtc::AudioDeviceModule* adm,
60 WebRtcVideoEncoderFactory* video_encoder_factory,
61 WebRtcVideoDecoderFactory* video_decoder_factory) {
gyzhou95aa9642016-12-13 14:06:26 -080062 return CreateWebRtcMediaEngine(
ossueb1fde42017-05-02 06:46:30 -070063 adm, webrtc::CreateBuiltinAudioEncoderFactory(),
64 webrtc::CreateBuiltinAudioDecoderFactory(), video_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070065 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
gyzhou95aa9642016-12-13 14:06:26 -080066}
67
68MediaEngineInterface* WebRtcMediaEngineFactory::Create(
69 webrtc::AudioDeviceModule* adm,
70 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
71 audio_decoder_factory,
72 WebRtcVideoEncoderFactory* video_encoder_factory,
73 WebRtcVideoDecoderFactory* video_decoder_factory) {
ossueb1fde42017-05-02 06:46:30 -070074 return CreateWebRtcMediaEngine(
75 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070076 video_encoder_factory, video_decoder_factory, nullptr,
77 webrtc::AudioProcessing::Create());
ossu111744e2016-06-15 02:22:32 -070078}
79
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000080// Used by PeerConnectionFactory to create a media engine passed into
81// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000082MediaEngineInterface* WebRtcMediaEngineFactory::Create(
83 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070084 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
85 audio_decoder_factory,
86 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080087 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070088 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
89 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
ossueb1fde42017-05-02 06:46:30 -070090 return CreateWebRtcMediaEngine(
91 adm, webrtc::CreateBuiltinAudioEncoderFactory(), audio_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070092 video_encoder_factory, video_decoder_factory, audio_mixer,
93 audio_processing);
ossueb1fde42017-05-02 06:46:30 -070094}
95
96MediaEngineInterface* WebRtcMediaEngineFactory::Create(
97 webrtc::AudioDeviceModule* adm,
98 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
99 audio_encoder_factory,
100 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
101 audio_decoder_factory,
102 WebRtcVideoEncoderFactory* video_encoder_factory,
103 WebRtcVideoDecoderFactory* video_decoder_factory) {
peaha9cc40b2017-06-29 08:32:09 -0700104 return CreateWebRtcMediaEngine(
105 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
106 video_decoder_factory, nullptr, webrtc::AudioProcessing::Create());
ossueb1fde42017-05-02 06:46:30 -0700107}
108
109MediaEngineInterface* WebRtcMediaEngineFactory::Create(
110 webrtc::AudioDeviceModule* adm,
111 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
112 audio_encoder_factory,
113 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
114 audio_decoder_factory,
115 WebRtcVideoEncoderFactory* video_encoder_factory,
116 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700117 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
118 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
119 return CreateWebRtcMediaEngine(
120 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
121 video_decoder_factory, audio_mixer, audio_processing);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000122}
123
solenberg7e4e01a2015-12-02 08:05:01 -0800124namespace {
125// Remove mutually exclusive extensions with lower priority.
126void DiscardRedundantExtensions(
127 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700128 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800129 RTC_DCHECK(extensions);
130 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700131 for (const char* uri : extensions_decreasing_prio) {
132 auto it = std::find_if(
133 extensions->begin(), extensions->end(),
134 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800135 if (it != extensions->end()) {
136 if (found) {
137 extensions->erase(it);
138 }
139 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100140 }
141 }
solenberg7e4e01a2015-12-02 08:05:01 -0800142}
143} // namespace
144
isheriff6f8d6862016-05-26 11:24:55 -0700145bool ValidateRtpExtensions(
146 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800147 bool id_used[14] = {false};
148 for (const auto& extension : extensions) {
149 if (extension.id <= 0 || extension.id >= 15) {
150 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
151 return false;
152 }
153 if (id_used[extension.id - 1]) {
154 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
155 return false;
156 }
157 id_used[extension.id - 1] = true;
158 }
159 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100160}
161
solenberg7e4e01a2015-12-02 08:05:01 -0800162std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700163 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800164 bool (*supported)(const std::string&),
165 bool filter_redundant_extensions) {
166 RTC_DCHECK(ValidateRtpExtensions(extensions));
167 RTC_DCHECK(supported);
168 std::vector<webrtc::RtpExtension> result;
169
170 // Ignore any extensions that we don't recognize.
171 for (const auto& extension : extensions) {
172 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700173 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800174 } else {
175 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
176 }
177 }
178
jbauch5869f502017-06-29 12:31:36 -0700179 // Sort by name, ascending (prioritise encryption), so that we don't reset
180 // extensions if they were specified in a different order (also allows us
181 // to use std::unique below).
solenberg7e4e01a2015-12-02 08:05:01 -0800182 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700183 [](const webrtc::RtpExtension& rhs,
jbauch5869f502017-06-29 12:31:36 -0700184 const webrtc::RtpExtension& lhs) {
185 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
186 : rhs.encrypt > lhs.encrypt;
187 });
solenberg7e4e01a2015-12-02 08:05:01 -0800188
189 // Remove unnecessary extensions (used on send side).
190 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700191 auto it = std::unique(
192 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800193 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700194 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800195 });
196 result.erase(it, result.end());
197
198 // Keep just the highest priority extension of any in the following list.
agrieve26622d32017-08-08 10:48:15 -0700199 static const char* const kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700200 webrtc::RtpExtension::kTransportSequenceNumberUri,
201 webrtc::RtpExtension::kAbsSendTimeUri,
202 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800203 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
204 }
205
206 return result;
207}
stefan13f1a0a2016-11-30 07:22:58 -0800208
209webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec(
210 const Codec& codec) {
211 webrtc::Call::Config::BitrateConfig config;
212 int bitrate_kbps = 0;
213 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
214 bitrate_kbps > 0) {
215 config.min_bitrate_bps = bitrate_kbps * 1000;
216 } else {
217 config.min_bitrate_bps = 0;
218 }
219 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
220 bitrate_kbps > 0) {
221 config.start_bitrate_bps = bitrate_kbps * 1000;
222 } else {
223 // Do not reconfigure start bitrate unless it's specified and positive.
224 config.start_bitrate_bps = -1;
225 }
226 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
227 bitrate_kbps > 0) {
228 config.max_bitrate_bps = bitrate_kbps * 1000;
229 } else {
230 config.max_bitrate_bps = -1;
231 }
232 return config;
233}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000234} // namespace cricket