blob: 9b5fef2478f3e26805b9959774ca45928e079796 [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"
16#include "webrtc/media/engine/webrtcvoiceengine.h"
17
jbauch4cb3e392016-01-26 13:07:54 -080018#ifdef HAVE_WEBRTC_VIDEO
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010019#include "webrtc/media/engine/webrtcvideoengine2.h"
jbauch4cb3e392016-01-26 13:07:54 -080020#else
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080022#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000023
24namespace cricket {
25
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000026class WebRtcMediaEngine2
jbauch4cb3e392016-01-26 13:07:54 -080027#ifdef HAVE_WEBRTC_VIDEO
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000028 : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
jbauch4cb3e392016-01-26 13:07:54 -080029#else
30 : public CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine> {
31#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000032 public:
33 WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070034 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
35 audio_decoder_factory,
36 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080037 WebRtcVideoDecoderFactory* video_decoder_factory,
38 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer)
solenbergff976312016-03-30 23:28:51 -070039#ifdef HAVE_WEBRTC_VIDEO
ossu29b1a8d2016-06-13 07:34:51 -070040 : CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2>(
gyzhou95aa9642016-12-13 14:06:26 -080041 adm,
42 audio_decoder_factory,
43 audio_mixer){
solenbergff976312016-03-30 23:28:51 -070044#else
ossu29b1a8d2016-06-13 07:34:51 -070045 : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
gyzhou95aa9642016-12-13 14:06:26 -080046 adm,
47 audio_decoder_factory,
48 audio_mixer) {
solenbergff976312016-03-30 23:28:51 -070049#endif
gyzhou95aa9642016-12-13 14:06:26 -080050 video_.SetExternalDecoderFactory(video_decoder_factory);
ossu29b1a8d2016-06-13 07:34:51 -070051 video_.SetExternalEncoderFactory(video_encoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000052 }
53};
henrike@webrtc.org0481f152014-08-19 14:56:59 +000054
55} // namespace cricket
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000056
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000057cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
58 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070059 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
60 audio_decoder_factory,
61 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -080062 cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
63 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
64 return new cricket::WebRtcMediaEngine2(adm, audio_decoder_factory,
65 video_encoder_factory,
66 video_decoder_factory, audio_mixer);
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000067}
68
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000069void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000070 delete media_engine;
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000071}
henrike@webrtc.org0481f152014-08-19 14:56:59 +000072
73namespace cricket {
74
ossu111744e2016-06-15 02:22:32 -070075// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
76// audio decoder factory is fully plumbed and used throughout WebRTC.
77// See: crbug.com/webrtc/6000
78MediaEngineInterface* WebRtcMediaEngineFactory::Create(
79 webrtc::AudioDeviceModule* adm,
80 WebRtcVideoEncoderFactory* video_encoder_factory,
81 WebRtcVideoDecoderFactory* video_decoder_factory) {
gyzhou95aa9642016-12-13 14:06:26 -080082 return CreateWebRtcMediaEngine(
83 adm, webrtc::CreateBuiltinAudioDecoderFactory(), video_encoder_factory,
84 video_decoder_factory, nullptr);
85}
86
87MediaEngineInterface* WebRtcMediaEngineFactory::Create(
88 webrtc::AudioDeviceModule* adm,
89 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
90 audio_decoder_factory,
91 WebRtcVideoEncoderFactory* video_encoder_factory,
92 WebRtcVideoDecoderFactory* video_decoder_factory) {
93 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
94 video_encoder_factory, video_decoder_factory,
95 nullptr);
ossu111744e2016-06-15 02:22:32 -070096}
97
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000098// Used by PeerConnectionFactory to create a media engine passed into
99// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000100MediaEngineInterface* WebRtcMediaEngineFactory::Create(
101 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -0700102 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
103 audio_decoder_factory,
104 WebRtcVideoEncoderFactory* video_encoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -0800105 WebRtcVideoDecoderFactory* video_decoder_factory,
106 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
ossu29b1a8d2016-06-13 07:34:51 -0700107 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
gyzhou95aa9642016-12-13 14:06:26 -0800108 video_encoder_factory, video_decoder_factory,
109 audio_mixer);
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000110}
111
solenberg7e4e01a2015-12-02 08:05:01 -0800112namespace {
113// Remove mutually exclusive extensions with lower priority.
114void DiscardRedundantExtensions(
115 std::vector<webrtc::RtpExtension>* extensions,
116 rtc::ArrayView<const char*> extensions_decreasing_prio) {
117 RTC_DCHECK(extensions);
118 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700119 for (const char* uri : extensions_decreasing_prio) {
120 auto it = std::find_if(
121 extensions->begin(), extensions->end(),
122 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800123 if (it != extensions->end()) {
124 if (found) {
125 extensions->erase(it);
126 }
127 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100128 }
129 }
solenberg7e4e01a2015-12-02 08:05:01 -0800130}
131} // namespace
132
isheriff6f8d6862016-05-26 11:24:55 -0700133bool ValidateRtpExtensions(
134 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800135 bool id_used[14] = {false};
136 for (const auto& extension : extensions) {
137 if (extension.id <= 0 || extension.id >= 15) {
138 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
139 return false;
140 }
141 if (id_used[extension.id - 1]) {
142 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
143 return false;
144 }
145 id_used[extension.id - 1] = true;
146 }
147 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100148}
149
solenberg7e4e01a2015-12-02 08:05:01 -0800150std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700151 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800152 bool (*supported)(const std::string&),
153 bool filter_redundant_extensions) {
154 RTC_DCHECK(ValidateRtpExtensions(extensions));
155 RTC_DCHECK(supported);
156 std::vector<webrtc::RtpExtension> result;
157
158 // Ignore any extensions that we don't recognize.
159 for (const auto& extension : extensions) {
160 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700161 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800162 } else {
163 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
164 }
165 }
166
167 // Sort by name, ascending, so that we don't reset extensions if they were
168 // specified in a different order (also allows us to use std::unique below).
169 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700170 [](const webrtc::RtpExtension& rhs,
171 const webrtc::RtpExtension& lhs) { return rhs.uri < lhs.uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800172
173 // Remove unnecessary extensions (used on send side).
174 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700175 auto it = std::unique(
176 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800177 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
isheriff6f8d6862016-05-26 11:24:55 -0700178 return rhs.uri == lhs.uri;
solenberg7e4e01a2015-12-02 08:05:01 -0800179 });
180 result.erase(it, result.end());
181
182 // Keep just the highest priority extension of any in the following list.
183 static const char* kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700184 webrtc::RtpExtension::kTransportSequenceNumberUri,
185 webrtc::RtpExtension::kAbsSendTimeUri,
186 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800187 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
188 }
189
190 return result;
191}
stefan13f1a0a2016-11-30 07:22:58 -0800192
193webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec(
194 const Codec& codec) {
195 webrtc::Call::Config::BitrateConfig config;
196 int bitrate_kbps = 0;
197 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
198 bitrate_kbps > 0) {
199 config.min_bitrate_bps = bitrate_kbps * 1000;
200 } else {
201 config.min_bitrate_bps = 0;
202 }
203 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
204 bitrate_kbps > 0) {
205 config.start_bitrate_bps = bitrate_kbps * 1000;
206 } else {
207 // Do not reconfigure start bitrate unless it's specified and positive.
208 config.start_bitrate_bps = -1;
209 }
210 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
211 bitrate_kbps > 0) {
212 config.max_bitrate_bps = bitrate_kbps * 1000;
213 } else {
214 config.max_bitrate_bps = -1;
215 }
216 return config;
217}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000218} // namespace cricket