blob: 45652d0128f9dcb50e2f412315f91379c9de85eb [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
jbauch4cb3e392016-01-26 13:07:54 -080015#ifdef HAVE_WEBRTC_VIDEO
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010016#include "webrtc/media/engine/webrtcvideoengine2.h"
jbauch4cb3e392016-01-26 13:07:54 -080017#else
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010018#include "webrtc/media/engine/nullwebrtcvideoengine.h"
jbauch4cb3e392016-01-26 13:07:54 -080019#endif
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010020#include "webrtc/media/engine/webrtcvoiceengine.h"
henrike@webrtc.org0481f152014-08-19 14:56:59 +000021
22namespace cricket {
23
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000024class WebRtcMediaEngine2
jbauch4cb3e392016-01-26 13:07:54 -080025#ifdef HAVE_WEBRTC_VIDEO
pbos@webrtc.orge77c9c82015-03-11 10:49:33 +000026 : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
jbauch4cb3e392016-01-26 13:07:54 -080027#else
28 : public CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine> {
29#endif
henrike@webrtc.org0481f152014-08-19 14:56:59 +000030 public:
31 WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
henrike@webrtc.org0481f152014-08-19 14:56:59 +000032 WebRtcVideoEncoderFactory* encoder_factory,
solenbergff976312016-03-30 23:28:51 -070033 WebRtcVideoDecoderFactory* decoder_factory)
34#ifdef HAVE_WEBRTC_VIDEO
35 : CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2>(adm) {
36#else
37 : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(adm) {
38#endif
pbos@webrtc.org0a2087a2014-09-23 09:40:22 +000039 video_.SetExternalDecoderFactory(decoder_factory);
40 video_.SetExternalEncoderFactory(encoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000041 }
42};
henrike@webrtc.org0481f152014-08-19 14:56:59 +000043
44} // namespace cricket
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000045
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000046cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
47 webrtc::AudioDeviceModule* adm,
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000048 cricket::WebRtcVideoEncoderFactory* encoder_factory,
49 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
Fredrik Solenbergccb49e72015-05-19 11:37:56 +020050 return new cricket::WebRtcMediaEngine2(adm, encoder_factory,
tommi@webrtc.orgb789f622015-03-22 12:50:30 +000051 decoder_factory);
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000052}
53
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000054void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000055 delete media_engine;
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000056}
henrike@webrtc.org0481f152014-08-19 14:56:59 +000057
58namespace cricket {
59
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000060// Used by PeerConnectionFactory to create a media engine passed into
61// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000062MediaEngineInterface* WebRtcMediaEngineFactory::Create(
63 webrtc::AudioDeviceModule* adm,
henrike@webrtc.org0481f152014-08-19 14:56:59 +000064 WebRtcVideoEncoderFactory* encoder_factory,
65 WebRtcVideoDecoderFactory* decoder_factory) {
Fredrik Solenbergccb49e72015-05-19 11:37:56 +020066 return CreateWebRtcMediaEngine(adm, encoder_factory, decoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000067}
68
solenberg7e4e01a2015-12-02 08:05:01 -080069namespace {
70// Remove mutually exclusive extensions with lower priority.
71void DiscardRedundantExtensions(
72 std::vector<webrtc::RtpExtension>* extensions,
73 rtc::ArrayView<const char*> extensions_decreasing_prio) {
74 RTC_DCHECK(extensions);
75 bool found = false;
76 for (const char* name : extensions_decreasing_prio) {
77 auto it = std::find_if(extensions->begin(), extensions->end(),
78 [name](const webrtc::RtpExtension& rhs) {
79 return rhs.name == name;
80 });
81 if (it != extensions->end()) {
82 if (found) {
83 extensions->erase(it);
84 }
85 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010086 }
87 }
solenberg7e4e01a2015-12-02 08:05:01 -080088}
89} // namespace
90
91bool ValidateRtpExtensions(const std::vector<RtpHeaderExtension>& extensions) {
92 bool id_used[14] = {false};
93 for (const auto& extension : extensions) {
94 if (extension.id <= 0 || extension.id >= 15) {
95 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
96 return false;
97 }
98 if (id_used[extension.id - 1]) {
99 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
100 return false;
101 }
102 id_used[extension.id - 1] = true;
103 }
104 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100105}
106
solenberg7e4e01a2015-12-02 08:05:01 -0800107std::vector<webrtc::RtpExtension> FilterRtpExtensions(
108 const std::vector<RtpHeaderExtension>& extensions,
109 bool (*supported)(const std::string&),
110 bool filter_redundant_extensions) {
111 RTC_DCHECK(ValidateRtpExtensions(extensions));
112 RTC_DCHECK(supported);
113 std::vector<webrtc::RtpExtension> result;
114
115 // Ignore any extensions that we don't recognize.
116 for (const auto& extension : extensions) {
117 if (supported(extension.uri)) {
118 result.push_back({extension.uri, extension.id});
119 } else {
120 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
121 }
122 }
123
124 // Sort by name, ascending, so that we don't reset extensions if they were
125 // specified in a different order (also allows us to use std::unique below).
126 std::sort(result.begin(), result.end(),
127 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
128 return rhs.name < lhs.name;
129 });
130
131 // Remove unnecessary extensions (used on send side).
132 if (filter_redundant_extensions) {
133 auto it = std::unique(result.begin(), result.end(),
134 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
135 return rhs.name == lhs.name;
136 });
137 result.erase(it, result.end());
138
139 // Keep just the highest priority extension of any in the following list.
140 static const char* kBweExtensionPriorities[] = {
141 kRtpTransportSequenceNumberHeaderExtension,
142 kRtpAbsoluteSenderTimeHeaderExtension,
143 kRtpTimestampOffsetHeaderExtension
144 };
145 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
146 }
147
148 return result;
149}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000150} // namespace cricket