blob: e60c592a3fabeed12eb58fed9a6b6ecd67fdf035 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "media/engine/webrtcmediaengine.h"
solenberg7e4e01a2015-12-02 08:05:01 -080012
13#include <algorithm>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <memory>
15#include <tuple>
16#include <utility>
solenberg7e4e01a2015-12-02 08:05:01 -080017
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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "media/engine/webrtcvoiceengine.h"
kwiberg087bd342017-02-10 08:15:44 -080021
jbauch4cb3e392016-01-26 13:07:54 -080022#ifdef HAVE_WEBRTC_VIDEO
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "media/engine/webrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080024#else
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080026#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000027
28namespace cricket {
29
Anders Carlssondd8c1652018-01-30 10:32:13 +010030#if defined(USE_BUILTIN_SW_CODECS)
magjed2475ae22017-09-12 04:42:15 -070031namespace {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000032
magjed2475ae22017-09-12 04:42:15 -070033MediaEngineInterface* CreateWebRtcMediaEngine(
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000034 webrtc::AudioDeviceModule* adm,
ossueb1fde42017-05-02 06:46:30 -070035 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
36 audio_encoder_factory,
ossu29b1a8d2016-06-13 07:34:51 -070037 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
38 audio_decoder_factory,
magjed2475ae22017-09-12 04:42:15 -070039 WebRtcVideoEncoderFactory* video_encoder_factory,
40 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070041 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
42 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
magjed2475ae22017-09-12 04:42:15 -070043#ifdef HAVE_WEBRTC_VIDEO
44 typedef WebRtcVideoEngine VideoEngine;
Magnus Jedvert02e7a192017-09-23 17:21:32 +020045 std::tuple<std::unique_ptr<WebRtcVideoEncoderFactory>,
46 std::unique_ptr<WebRtcVideoDecoderFactory>>
47 video_args(
48 (std::unique_ptr<WebRtcVideoEncoderFactory>(video_encoder_factory)),
49 (std::unique_ptr<WebRtcVideoDecoderFactory>(video_decoder_factory)));
magjed2475ae22017-09-12 04:42:15 -070050#else
51 typedef NullWebRtcVideoEngine VideoEngine;
52 std::tuple<> video_args;
53#endif
54 return new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
55 std::forward_as_tuple(adm, audio_encoder_factory, audio_decoder_factory,
56 audio_mixer, audio_processing),
57 std::move(video_args));
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000058}
59
magjed2475ae22017-09-12 04:42:15 -070060} // namespace
henrike@webrtc.org0481f152014-08-19 14:56:59 +000061
ossueb1fde42017-05-02 06:46:30 -070062MediaEngineInterface* WebRtcMediaEngineFactory::Create(
63 webrtc::AudioDeviceModule* adm,
64 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
65 audio_encoder_factory,
66 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
67 audio_decoder_factory,
68 WebRtcVideoEncoderFactory* video_encoder_factory,
69 WebRtcVideoDecoderFactory* video_decoder_factory) {
Ivo Creusen62337e52018-01-09 14:17:33 +010070 return CreateWebRtcMediaEngine(adm, audio_encoder_factory,
71 audio_decoder_factory, video_encoder_factory,
72 video_decoder_factory, nullptr,
73 webrtc::AudioProcessingBuilder().Create());
ossueb1fde42017-05-02 06:46:30 -070074}
75
76MediaEngineInterface* WebRtcMediaEngineFactory::Create(
77 webrtc::AudioDeviceModule* adm,
78 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
79 audio_encoder_factory,
80 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
81 audio_decoder_factory,
82 WebRtcVideoEncoderFactory* video_encoder_factory,
83 WebRtcVideoDecoderFactory* video_decoder_factory,
peaha9cc40b2017-06-29 08:32:09 -070084 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
85 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
86 return CreateWebRtcMediaEngine(
87 adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory,
88 video_decoder_factory, audio_mixer, audio_processing);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000089}
Anders Carlssondd8c1652018-01-30 10:32:13 +010090#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000091
Magnus Jedvert58b03162017-09-15 19:02:47 +020092std::unique_ptr<MediaEngineInterface> WebRtcMediaEngineFactory::Create(
93 rtc::scoped_refptr<webrtc::AudioDeviceModule> adm,
94 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
95 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
96 std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
97 std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory,
98 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
99 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
100#ifdef HAVE_WEBRTC_VIDEO
101 typedef WebRtcVideoEngine VideoEngine;
102 std::tuple<std::unique_ptr<webrtc::VideoEncoderFactory>,
103 std::unique_ptr<webrtc::VideoDecoderFactory>>
104 video_args(std::move(video_encoder_factory),
105 std::move(video_decoder_factory));
106#else
107 typedef NullWebRtcVideoEngine VideoEngine;
108 std::tuple<> video_args;
109#endif
110 return std::unique_ptr<MediaEngineInterface>(
111 new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
112 std::forward_as_tuple(adm, audio_encoder_factory,
113 audio_decoder_factory, audio_mixer,
114 audio_processing),
115 std::move(video_args)));
116}
117
solenberg7e4e01a2015-12-02 08:05:01 -0800118namespace {
119// Remove mutually exclusive extensions with lower priority.
120void DiscardRedundantExtensions(
121 std::vector<webrtc::RtpExtension>* extensions,
agrieve26622d32017-08-08 10:48:15 -0700122 rtc::ArrayView<const char* const> extensions_decreasing_prio) {
solenberg7e4e01a2015-12-02 08:05:01 -0800123 RTC_DCHECK(extensions);
124 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -0700125 for (const char* uri : extensions_decreasing_prio) {
126 auto it = std::find_if(
127 extensions->begin(), extensions->end(),
128 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800129 if (it != extensions->end()) {
130 if (found) {
131 extensions->erase(it);
132 }
133 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100134 }
135 }
solenberg7e4e01a2015-12-02 08:05:01 -0800136}
137} // namespace
138
isheriff6f8d6862016-05-26 11:24:55 -0700139bool ValidateRtpExtensions(
140 const std::vector<webrtc::RtpExtension>& extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200141 bool id_used[1 + webrtc::RtpExtension::kMaxId] = {false};
solenberg7e4e01a2015-12-02 08:05:01 -0800142 for (const auto& extension : extensions) {
Johannes Kron07ba2b92018-09-26 13:33:35 +0200143 if (extension.id < webrtc::RtpExtension::kMinId ||
144 extension.id > webrtc::RtpExtension::kMaxId) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100145 RTC_LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800146 return false;
147 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200148 if (id_used[extension.id]) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100149 RTC_LOG(LS_ERROR) << "Duplicate RTP extension ID: "
150 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800151 return false;
152 }
Johannes Kron07ba2b92018-09-26 13:33:35 +0200153 id_used[extension.id] = true;
solenberg7e4e01a2015-12-02 08:05:01 -0800154 }
155 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100156}
157
solenberg7e4e01a2015-12-02 08:05:01 -0800158std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700159 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800160 bool (*supported)(const std::string&),
161 bool filter_redundant_extensions) {
162 RTC_DCHECK(ValidateRtpExtensions(extensions));
163 RTC_DCHECK(supported);
164 std::vector<webrtc::RtpExtension> result;
165
166 // Ignore any extensions that we don't recognize.
167 for (const auto& extension : extensions) {
168 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700169 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800170 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100171 RTC_LOG(LS_WARNING) << "Unsupported RTP extension: "
172 << extension.ToString();
solenberg7e4e01a2015-12-02 08:05:01 -0800173 }
174 }
175
jbauch5869f502017-06-29 12:31:36 -0700176 // Sort by name, ascending (prioritise encryption), so that we don't reset
177 // extensions if they were specified in a different order (also allows us
178 // to use std::unique below).
Yves Gerey665174f2018-06-19 15:03:05 +0200179 std::sort(
180 result.begin(), result.end(),
181 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
182 return rhs.encrypt == lhs.encrypt ? rhs.uri < lhs.uri
183 : rhs.encrypt > lhs.encrypt;
184 });
solenberg7e4e01a2015-12-02 08:05:01 -0800185
186 // Remove unnecessary extensions (used on send side).
187 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700188 auto it = std::unique(
189 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800190 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
jbauch5869f502017-06-29 12:31:36 -0700191 return rhs.uri == lhs.uri && rhs.encrypt == lhs.encrypt;
solenberg7e4e01a2015-12-02 08:05:01 -0800192 });
193 result.erase(it, result.end());
194
195 // Keep just the highest priority extension of any in the following list.
agrieve26622d32017-08-08 10:48:15 -0700196 static const char* const kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700197 webrtc::RtpExtension::kTransportSequenceNumberUri,
198 webrtc::RtpExtension::kAbsSendTimeUri,
199 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800200 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
201 }
202
203 return result;
204}
stefan13f1a0a2016-11-30 07:22:58 -0800205
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100206webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec) {
207 webrtc::BitrateConstraints config;
stefan13f1a0a2016-11-30 07:22:58 -0800208 int bitrate_kbps = 0;
209 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) &&
210 bitrate_kbps > 0) {
211 config.min_bitrate_bps = bitrate_kbps * 1000;
212 } else {
213 config.min_bitrate_bps = 0;
214 }
215 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) &&
216 bitrate_kbps > 0) {
217 config.start_bitrate_bps = bitrate_kbps * 1000;
218 } else {
219 // Do not reconfigure start bitrate unless it's specified and positive.
220 config.start_bitrate_bps = -1;
221 }
222 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) &&
223 bitrate_kbps > 0) {
224 config.max_bitrate_bps = bitrate_kbps * 1000;
225 } else {
226 config.max_bitrate_bps = -1;
227 }
228 return config;
229}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000230} // namespace cricket