summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/media/base/media_engine.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/media/base/media_engine.cc')
-rw-r--r--third_party/libwebrtc/media/base/media_engine.cc291
1 files changed, 291 insertions, 0 deletions
diff --git a/third_party/libwebrtc/media/base/media_engine.cc b/third_party/libwebrtc/media/base/media_engine.cc
new file mode 100644
index 0000000000..7304ab03d7
--- /dev/null
+++ b/third_party/libwebrtc/media/base/media_engine.cc
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "media/base/media_engine.h"
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/algorithm/container.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/string_encode.h"
+
+namespace cricket {
+
+RtpCapabilities::RtpCapabilities() = default;
+RtpCapabilities::~RtpCapabilities() = default;
+
+webrtc::RtpParameters CreateRtpParametersWithOneEncoding() {
+ webrtc::RtpParameters parameters;
+ webrtc::RtpEncodingParameters encoding;
+ parameters.encodings.push_back(encoding);
+ return parameters;
+}
+
+webrtc::RtpParameters CreateRtpParametersWithEncodings(StreamParams sp) {
+ std::vector<uint32_t> primary_ssrcs;
+ sp.GetPrimarySsrcs(&primary_ssrcs);
+ size_t encoding_count = primary_ssrcs.size();
+
+ std::vector<webrtc::RtpEncodingParameters> encodings(encoding_count);
+ for (size_t i = 0; i < encodings.size(); ++i) {
+ encodings[i].ssrc = primary_ssrcs[i];
+ }
+
+ const std::vector<RidDescription>& rids = sp.rids();
+ RTC_DCHECK(rids.size() == 0 || rids.size() == encoding_count);
+ for (size_t i = 0; i < rids.size(); ++i) {
+ encodings[i].rid = rids[i].rid;
+ }
+
+ webrtc::RtpParameters parameters;
+ parameters.encodings = encodings;
+ parameters.rtcp.cname = sp.cname;
+ return parameters;
+}
+
+std::vector<webrtc::RtpExtension> GetDefaultEnabledRtpHeaderExtensions(
+ const RtpHeaderExtensionQueryInterface& query_interface) {
+ std::vector<webrtc::RtpExtension> extensions;
+ for (const auto& entry : query_interface.GetRtpHeaderExtensions()) {
+ if (entry.direction != webrtc::RtpTransceiverDirection::kStopped)
+ extensions.emplace_back(entry.uri, *entry.preferred_id);
+ }
+ return extensions;
+}
+
+webrtc::RTCError CheckScalabilityModeValues(
+ const webrtc::RtpParameters& rtp_parameters,
+ rtc::ArrayView<cricket::Codec> codec_preferences,
+ absl::optional<cricket::Codec> send_codec) {
+ using webrtc::RTCErrorType;
+
+ if (codec_preferences.empty()) {
+ // This is an audio sender or an extra check in the stack where the codec
+ // list is not available and we can't check the scalability_mode values.
+ return webrtc::RTCError::OK();
+ }
+
+ for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) {
+ if (rtp_parameters.encodings[i].codec) {
+ bool codecFound = false;
+ for (const cricket::VideoCodec& codec : codec_preferences) {
+ if (codec.MatchesRtpCodec(*rtp_parameters.encodings[i].codec)) {
+ codecFound = true;
+ send_codec = codec;
+ break;
+ }
+ }
+ if (!codecFound) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to use an unsupported codec for layer " +
+ std::to_string(i));
+ }
+ }
+ if (rtp_parameters.encodings[i].scalability_mode) {
+ if (!send_codec) {
+ bool scalabilityModeFound = false;
+ for (const cricket::VideoCodec& codec : codec_preferences) {
+ for (const auto& scalability_mode : codec.scalability_modes) {
+ if (ScalabilityModeToString(scalability_mode) ==
+ *rtp_parameters.encodings[i].scalability_mode) {
+ scalabilityModeFound = true;
+ break;
+ }
+ }
+ if (scalabilityModeFound)
+ break;
+ }
+
+ if (!scalabilityModeFound) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters scalabilityMode "
+ "to an unsupported value for the current codecs.");
+ }
+ } else {
+ bool scalabilityModeFound = false;
+ for (const auto& scalability_mode : send_codec->scalability_modes) {
+ if (ScalabilityModeToString(scalability_mode) ==
+ *rtp_parameters.encodings[i].scalability_mode) {
+ scalabilityModeFound = true;
+ break;
+ }
+ }
+ if (!scalabilityModeFound) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters scalabilityMode "
+ "to an unsupported value for the current codecs.");
+ }
+ }
+ }
+ }
+
+ return webrtc::RTCError::OK();
+}
+
+webrtc::RTCError CheckRtpParametersValues(
+ const webrtc::RtpParameters& rtp_parameters,
+ rtc::ArrayView<cricket::Codec> codec_preferences,
+ absl::optional<cricket::Codec> send_codec) {
+ using webrtc::RTCErrorType;
+
+ for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) {
+ if (rtp_parameters.encodings[i].bitrate_priority <= 0) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
+ "Attempted to set RtpParameters bitrate_priority to "
+ "an invalid number. bitrate_priority must be > 0.");
+ }
+ if (rtp_parameters.encodings[i].scale_resolution_down_by &&
+ *rtp_parameters.encodings[i].scale_resolution_down_by < 1.0) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_RANGE,
+ "Attempted to set RtpParameters scale_resolution_down_by to an "
+ "invalid value. scale_resolution_down_by must be >= 1.0");
+ }
+ if (rtp_parameters.encodings[i].max_framerate &&
+ *rtp_parameters.encodings[i].max_framerate < 0.0) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
+ "Attempted to set RtpParameters max_framerate to an "
+ "invalid value. max_framerate must be >= 0.0");
+ }
+ if (rtp_parameters.encodings[i].min_bitrate_bps &&
+ rtp_parameters.encodings[i].max_bitrate_bps) {
+ if (*rtp_parameters.encodings[i].max_bitrate_bps <
+ *rtp_parameters.encodings[i].min_bitrate_bps) {
+ LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::INVALID_RANGE,
+ "Attempted to set RtpParameters min bitrate "
+ "larger than max bitrate.");
+ }
+ }
+ if (rtp_parameters.encodings[i].num_temporal_layers) {
+ if (*rtp_parameters.encodings[i].num_temporal_layers < 1 ||
+ *rtp_parameters.encodings[i].num_temporal_layers >
+ webrtc::kMaxTemporalStreams) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
+ "Attempted to set RtpParameters "
+ "num_temporal_layers to an invalid number.");
+ }
+ }
+
+ if (rtp_parameters.encodings[i].requested_resolution &&
+ rtp_parameters.encodings[i].scale_resolution_down_by) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
+ "Attempted to set scale_resolution_down_by and "
+ "requested_resolution simultaniously.");
+ }
+
+ if (i > 0 && rtp_parameters.encodings[i - 1].codec !=
+ rtp_parameters.encodings[i].codec) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
+ "Attempted to use different codec values for "
+ "different encodings.");
+ }
+ }
+
+ return CheckScalabilityModeValues(rtp_parameters, codec_preferences,
+ send_codec);
+}
+
+webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
+ const webrtc::RtpParameters& old_rtp_parameters,
+ const webrtc::RtpParameters& rtp_parameters) {
+ return CheckRtpParametersInvalidModificationAndValues(
+ old_rtp_parameters, rtp_parameters, {}, absl::nullopt);
+}
+
+webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
+ const webrtc::RtpParameters& old_rtp_parameters,
+ const webrtc::RtpParameters& rtp_parameters,
+ rtc::ArrayView<cricket::Codec> codec_preferences,
+ absl::optional<cricket::Codec> send_codec) {
+ using webrtc::RTCErrorType;
+ if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters with different encoding count");
+ }
+ if (rtp_parameters.rtcp != old_rtp_parameters.rtcp) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters with modified RTCP parameters");
+ }
+ if (rtp_parameters.header_extensions !=
+ old_rtp_parameters.header_extensions) {
+ LOG_AND_RETURN_ERROR(
+ RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters with modified header extensions");
+ }
+ if (!absl::c_equal(old_rtp_parameters.encodings, rtp_parameters.encodings,
+ [](const webrtc::RtpEncodingParameters& encoding1,
+ const webrtc::RtpEncodingParameters& encoding2) {
+ return encoding1.rid == encoding2.rid;
+ })) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to change RID values in the encodings.");
+ }
+ if (!absl::c_equal(old_rtp_parameters.encodings, rtp_parameters.encodings,
+ [](const webrtc::RtpEncodingParameters& encoding1,
+ const webrtc::RtpEncodingParameters& encoding2) {
+ return encoding1.ssrc == encoding2.ssrc;
+ })) {
+ LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
+ "Attempted to set RtpParameters with modified SSRC");
+ }
+
+ return CheckRtpParametersValues(rtp_parameters, codec_preferences,
+ send_codec);
+}
+
+CompositeMediaEngine::CompositeMediaEngine(
+ std::unique_ptr<webrtc::FieldTrialsView> trials,
+ std::unique_ptr<VoiceEngineInterface> audio_engine,
+ std::unique_ptr<VideoEngineInterface> video_engine)
+ : trials_(std::move(trials)),
+ voice_engine_(std::move(audio_engine)),
+ video_engine_(std::move(video_engine)) {}
+
+CompositeMediaEngine::CompositeMediaEngine(
+ std::unique_ptr<VoiceEngineInterface> audio_engine,
+ std::unique_ptr<VideoEngineInterface> video_engine)
+ : CompositeMediaEngine(nullptr,
+ std::move(audio_engine),
+ std::move(video_engine)) {}
+
+CompositeMediaEngine::~CompositeMediaEngine() = default;
+
+bool CompositeMediaEngine::Init() {
+ voice().Init();
+ return true;
+}
+
+VoiceEngineInterface& CompositeMediaEngine::voice() {
+ return *voice_engine_.get();
+}
+
+VideoEngineInterface& CompositeMediaEngine::video() {
+ return *video_engine_.get();
+}
+
+const VoiceEngineInterface& CompositeMediaEngine::voice() const {
+ return *voice_engine_.get();
+}
+
+const VideoEngineInterface& CompositeMediaEngine::video() const {
+ return *video_engine_.get();
+}
+
+} // namespace cricket