blob: 51a110b88b645aa2678991a9abede312f34463b7 [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"
ossu111744e2016-06-15 02:22:32 -070012#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
solenberg7e4e01a2015-12-02 08:05:01 -080013
14#include <algorithm>
15
jbauch4cb3e392016-01-26 13:07:54 -080016#ifdef HAVE_WEBRTC_VIDEO
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010017#include "webrtc/media/engine/webrtcvideoengine2.h"
jbauch4cb3e392016-01-26 13:07:54 -080018#else
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010019#include "webrtc/media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080020#endif
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/webrtcvoiceengine.h"
henrike@webrtc.org0481f152014-08-19 14:56:59 +000022
23namespace cricket {
24
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000025class WebRtcMediaEngine2
jbauch4cb3e392016-01-26 13:07:54 -080026#ifdef HAVE_WEBRTC_VIDEO
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000027 : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
jbauch4cb3e392016-01-26 13:07:54 -080028#else
29 : public CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine> {
30#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000031 public:
32 WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070033 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
34 audio_decoder_factory,
35 WebRtcVideoEncoderFactory* video_encoder_factory,
36 WebRtcVideoDecoderFactory* video_decoder_factory)
solenbergff976312016-03-30 23:28:51 -070037#ifdef HAVE_WEBRTC_VIDEO
ossu29b1a8d2016-06-13 07:34:51 -070038 : CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2>(
39 adm, audio_decoder_factory){
solenbergff976312016-03-30 23:28:51 -070040#else
ossu29b1a8d2016-06-13 07:34:51 -070041 : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
42 adm, audio_decoder_factory) {
solenbergff976312016-03-30 23:28:51 -070043#endif
ossu29b1a8d2016-06-13 07:34:51 -070044 video_.SetExternalDecoderFactory(video_decoder_factory);
45 video_.SetExternalEncoderFactory(video_encoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000046 }
47};
henrike@webrtc.org0481f152014-08-19 14:56:59 +000048
49} // namespace cricket
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000050
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000051cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
52 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070053 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
54 audio_decoder_factory,
55 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
56 cricket::WebRtcVideoDecoderFactory* video_decoder_factory) {
57 return new cricket::WebRtcMediaEngine2(
58 adm, audio_decoder_factory, video_encoder_factory, video_decoder_factory);
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000059}
60
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000061void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000062 delete media_engine;
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000063}
henrike@webrtc.org0481f152014-08-19 14:56:59 +000064
65namespace cricket {
66
ossu111744e2016-06-15 02:22:32 -070067// TODO(ossu): Backwards-compatible interface. Will be deprecated once the
68// audio decoder factory is fully plumbed and used throughout WebRTC.
69// See: crbug.com/webrtc/6000
70MediaEngineInterface* WebRtcMediaEngineFactory::Create(
71 webrtc::AudioDeviceModule* adm,
72 WebRtcVideoEncoderFactory* video_encoder_factory,
73 WebRtcVideoDecoderFactory* video_decoder_factory) {
74 return CreateWebRtcMediaEngine(adm,
75 webrtc::CreateBuiltinAudioDecoderFactory(),
76 video_encoder_factory, video_decoder_factory);
77}
78
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000079// Used by PeerConnectionFactory to create a media engine passed into
80// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000081MediaEngineInterface* WebRtcMediaEngineFactory::Create(
82 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070083 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
84 audio_decoder_factory,
85 WebRtcVideoEncoderFactory* video_encoder_factory,
86 WebRtcVideoDecoderFactory* video_decoder_factory) {
87 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
88 video_encoder_factory, video_decoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000089}
90
solenberg7e4e01a2015-12-02 08:05:01 -080091namespace {
92// Remove mutually exclusive extensions with lower priority.
93void DiscardRedundantExtensions(
94 std::vector<webrtc::RtpExtension>* extensions,
95 rtc::ArrayView<const char*> extensions_decreasing_prio) {
96 RTC_DCHECK(extensions);
97 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -070098 for (const char* uri : extensions_decreasing_prio) {
99 auto it = std::find_if(
100 extensions->begin(), extensions->end(),
101 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800102 if (it != extensions->end()) {
103 if (found) {
104 extensions->erase(it);
105 }
106 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100107 }
108 }
solenberg7e4e01a2015-12-02 08:05:01 -0800109}
110} // namespace
111
isheriff6f8d6862016-05-26 11:24:55 -0700112bool ValidateRtpExtensions(
113 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800114 bool id_used[14] = {false};
115 for (const auto& extension : extensions) {
116 if (extension.id <= 0 || extension.id >= 15) {
117 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
118 return false;
119 }
120 if (id_used[extension.id - 1]) {
121 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
122 return false;
123 }
124 id_used[extension.id - 1] = true;
125 }
126 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100127}
128
solenberg7e4e01a2015-12-02 08:05:01 -0800129std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700130 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800131 bool (*supported)(const std::string&),
132 bool filter_redundant_extensions) {
133 RTC_DCHECK(ValidateRtpExtensions(extensions));
134 RTC_DCHECK(supported);
135 std::vector<webrtc::RtpExtension> result;
136
137 // Ignore any extensions that we don't recognize.
138 for (const auto& extension : extensions) {
139 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700140 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800141 } else {
142 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
143 }
144 }
145
146 // Sort by name, ascending, so that we don't reset extensions if they were
147 // specified in a different order (also allows us to use std::unique below).
148 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700149 [](const webrtc::RtpExtension& rhs,
150 const webrtc::RtpExtension& lhs) { return rhs.uri < lhs.uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800151
152 // Remove unnecessary extensions (used on send side).
153 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700154 auto it = std::unique(
155 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800156 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
isheriff6f8d6862016-05-26 11:24:55 -0700157 return rhs.uri == lhs.uri;
solenberg7e4e01a2015-12-02 08:05:01 -0800158 });
159 result.erase(it, result.end());
160
161 // Keep just the highest priority extension of any in the following list.
162 static const char* kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700163 webrtc::RtpExtension::kTransportSequenceNumberUri,
164 webrtc::RtpExtension::kAbsSendTimeUri,
165 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800166 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
167 }
168
169 return result;
170}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000171} // namespace cricket