blob: 53e15d657543625e31b5aa9964ef1aad427b7861 [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,
ossu29b1a8d2016-06-13 07:34:51 -070032 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
33 audio_decoder_factory,
34 WebRtcVideoEncoderFactory* video_encoder_factory,
35 WebRtcVideoDecoderFactory* video_decoder_factory)
solenbergff976312016-03-30 23:28:51 -070036#ifdef HAVE_WEBRTC_VIDEO
ossu29b1a8d2016-06-13 07:34:51 -070037 : CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2>(
38 adm, audio_decoder_factory){
solenbergff976312016-03-30 23:28:51 -070039#else
ossu29b1a8d2016-06-13 07:34:51 -070040 : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
41 adm, audio_decoder_factory) {
solenbergff976312016-03-30 23:28:51 -070042#endif
ossu29b1a8d2016-06-13 07:34:51 -070043 video_.SetExternalDecoderFactory(video_decoder_factory);
44 video_.SetExternalEncoderFactory(video_encoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000045 }
46};
henrike@webrtc.org0481f152014-08-19 14:56:59 +000047
48} // namespace cricket
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000049
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000050cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
51 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070052 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
53 audio_decoder_factory,
54 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
55 cricket::WebRtcVideoDecoderFactory* video_decoder_factory) {
56 return new cricket::WebRtcMediaEngine2(
57 adm, audio_decoder_factory, video_encoder_factory, video_decoder_factory);
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000058}
59
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000060void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
henrike@webrtc.org0481f152014-08-19 14:56:59 +000061 delete media_engine;
pbos@webrtc.org9e65a3b2014-06-11 13:42:37 +000062}
henrike@webrtc.org0481f152014-08-19 14:56:59 +000063
64namespace cricket {
65
buildbot@webrtc.org95bbd182014-08-20 07:49:30 +000066// Used by PeerConnectionFactory to create a media engine passed into
67// ChannelManager.
henrike@webrtc.org0481f152014-08-19 14:56:59 +000068MediaEngineInterface* WebRtcMediaEngineFactory::Create(
69 webrtc::AudioDeviceModule* adm,
ossu29b1a8d2016-06-13 07:34:51 -070070 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
71 audio_decoder_factory,
72 WebRtcVideoEncoderFactory* video_encoder_factory,
73 WebRtcVideoDecoderFactory* video_decoder_factory) {
74 return CreateWebRtcMediaEngine(adm, audio_decoder_factory,
75 video_encoder_factory, video_decoder_factory);
henrike@webrtc.org0481f152014-08-19 14:56:59 +000076}
77
solenberg7e4e01a2015-12-02 08:05:01 -080078namespace {
79// Remove mutually exclusive extensions with lower priority.
80void DiscardRedundantExtensions(
81 std::vector<webrtc::RtpExtension>* extensions,
82 rtc::ArrayView<const char*> extensions_decreasing_prio) {
83 RTC_DCHECK(extensions);
84 bool found = false;
isheriff6f8d6862016-05-26 11:24:55 -070085 for (const char* uri : extensions_decreasing_prio) {
86 auto it = std::find_if(
87 extensions->begin(), extensions->end(),
88 [uri](const webrtc::RtpExtension& rhs) { return rhs.uri == uri; });
solenberg7e4e01a2015-12-02 08:05:01 -080089 if (it != extensions->end()) {
90 if (found) {
91 extensions->erase(it);
92 }
93 found = true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +010094 }
95 }
solenberg7e4e01a2015-12-02 08:05:01 -080096}
97} // namespace
98
isheriff6f8d6862016-05-26 11:24:55 -070099bool ValidateRtpExtensions(
100 const std::vector<webrtc::RtpExtension>& extensions) {
solenberg7e4e01a2015-12-02 08:05:01 -0800101 bool id_used[14] = {false};
102 for (const auto& extension : extensions) {
103 if (extension.id <= 0 || extension.id >= 15) {
104 LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
105 return false;
106 }
107 if (id_used[extension.id - 1]) {
108 LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
109 return false;
110 }
111 id_used[extension.id - 1] = true;
112 }
113 return true;
Stefan Holmerbbaf3632015-10-29 18:53:23 +0100114}
115
solenberg7e4e01a2015-12-02 08:05:01 -0800116std::vector<webrtc::RtpExtension> FilterRtpExtensions(
isheriff6f8d6862016-05-26 11:24:55 -0700117 const std::vector<webrtc::RtpExtension>& extensions,
solenberg7e4e01a2015-12-02 08:05:01 -0800118 bool (*supported)(const std::string&),
119 bool filter_redundant_extensions) {
120 RTC_DCHECK(ValidateRtpExtensions(extensions));
121 RTC_DCHECK(supported);
122 std::vector<webrtc::RtpExtension> result;
123
124 // Ignore any extensions that we don't recognize.
125 for (const auto& extension : extensions) {
126 if (supported(extension.uri)) {
isheriff6f8d6862016-05-26 11:24:55 -0700127 result.push_back(extension);
solenberg7e4e01a2015-12-02 08:05:01 -0800128 } else {
129 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
130 }
131 }
132
133 // Sort by name, ascending, so that we don't reset extensions if they were
134 // specified in a different order (also allows us to use std::unique below).
135 std::sort(result.begin(), result.end(),
isheriff6f8d6862016-05-26 11:24:55 -0700136 [](const webrtc::RtpExtension& rhs,
137 const webrtc::RtpExtension& lhs) { return rhs.uri < lhs.uri; });
solenberg7e4e01a2015-12-02 08:05:01 -0800138
139 // Remove unnecessary extensions (used on send side).
140 if (filter_redundant_extensions) {
isheriff6f8d6862016-05-26 11:24:55 -0700141 auto it = std::unique(
142 result.begin(), result.end(),
solenberg7e4e01a2015-12-02 08:05:01 -0800143 [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
isheriff6f8d6862016-05-26 11:24:55 -0700144 return rhs.uri == lhs.uri;
solenberg7e4e01a2015-12-02 08:05:01 -0800145 });
146 result.erase(it, result.end());
147
148 // Keep just the highest priority extension of any in the following list.
149 static const char* kBweExtensionPriorities[] = {
isheriff6f8d6862016-05-26 11:24:55 -0700150 webrtc::RtpExtension::kTransportSequenceNumberUri,
151 webrtc::RtpExtension::kAbsSendTimeUri,
152 webrtc::RtpExtension::kTimestampOffsetUri};
solenberg7e4e01a2015-12-02 08:05:01 -0800153 DiscardRedundantExtensions(&result, kBweExtensionPriorities);
154 }
155
156 return result;
157}
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000158} // namespace cricket