1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  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.
9  */
10 
11 #ifndef TEST_PC_E2E_SDP_SDP_CHANGER_H_
12 #define TEST_PC_E2E_SDP_SDP_CHANGER_H_
13 
14 #include <map>
15 #include <string>
16 #include <vector>
17 
18 #include "absl/strings/string_view.h"
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "api/jsep.h"
22 #include "api/rtp_parameters.h"
23 #include "api/test/peerconnection_quality_test_fixture.h"
24 #include "media/base/rid_description.h"
25 #include "pc/session_description.h"
26 #include "pc/simulcast_description.h"
27 
28 namespace webrtc {
29 namespace webrtc_pc_e2e {
30 
31 // Creates list of capabilities, which can be set on RtpTransceiverInterface via
32 // RtpTransceiverInterface::SetCodecPreferences(...) to negotiate use of codecs
33 // from list of |supported_codecs| which will match |video_codecs|. If flags
34 // |ulpfec| or |flexfec| set to true corresponding FEC codec will be added.
35 // FEC and RTX codecs will be added after required codecs.
36 //
37 // All codecs will be added only if they exists in the list of
38 // |supported_codecs|. If multiple codecs from this list will match
39 // |video_codecs|, then all of them will be added to the output
40 // vector and they will be added in the same order, as they were in
41 // |supported_codecs|.
42 std::vector<RtpCodecCapability> FilterVideoCodecCapabilities(
43     rtc::ArrayView<const PeerConnectionE2EQualityTestFixture::VideoCodecConfig>
44         video_codecs,
45     bool use_rtx,
46     bool use_ulpfec,
47     bool use_flexfec,
48     rtc::ArrayView<const RtpCodecCapability> supported_codecs);
49 
50 struct LocalAndRemoteSdp {
LocalAndRemoteSdpLocalAndRemoteSdp51   LocalAndRemoteSdp(std::unique_ptr<SessionDescriptionInterface> local_sdp,
52                     std::unique_ptr<SessionDescriptionInterface> remote_sdp)
53       : local_sdp(std::move(local_sdp)), remote_sdp(std::move(remote_sdp)) {}
54 
55   // Sdp, that should be as local description on the peer, that created it.
56   std::unique_ptr<SessionDescriptionInterface> local_sdp;
57   // Sdp, that should be set as remote description on the peer opposite to the
58   // one, who created it.
59   std::unique_ptr<SessionDescriptionInterface> remote_sdp;
60 };
61 
62 struct PatchingParams {
PatchingParamsPatchingParams63   PatchingParams(
64       std::vector<PeerConnectionE2EQualityTestFixture::VideoCodecConfig>
65           video_codecs,
66       bool use_conference_mode,
67       std::map<std::string, int> stream_label_to_simulcast_streams_count)
68       : video_codecs(std::move(video_codecs)),
69         use_conference_mode(use_conference_mode),
70         stream_label_to_simulcast_streams_count(
71             stream_label_to_simulcast_streams_count) {}
72 
73   std::vector<PeerConnectionE2EQualityTestFixture::VideoCodecConfig>
74       video_codecs;
75   bool use_conference_mode;
76   std::map<std::string, int> stream_label_to_simulcast_streams_count;
77 };
78 
79 class SignalingInterceptor {
80  public:
SignalingInterceptor(PatchingParams params)81   explicit SignalingInterceptor(PatchingParams params) : params_(params) {}
82 
83   LocalAndRemoteSdp PatchOffer(
84       std::unique_ptr<SessionDescriptionInterface> offer);
85   LocalAndRemoteSdp PatchAnswer(
86       std::unique_ptr<SessionDescriptionInterface> offer);
87 
88   std::vector<std::unique_ptr<IceCandidateInterface>> PatchOffererIceCandidates(
89       rtc::ArrayView<const IceCandidateInterface* const> candidates);
90   std::vector<std::unique_ptr<IceCandidateInterface>>
91   PatchAnswererIceCandidates(
92       rtc::ArrayView<const IceCandidateInterface* const> candidates);
93 
94  private:
95   // Contains information about simulcast section, that is required to perform
96   // modified offer/answer and ice candidates exchange.
97   struct SimulcastSectionInfo {
98     SimulcastSectionInfo(const std::string& mid,
99                          cricket::MediaProtocolType media_protocol_type,
100                          const std::vector<cricket::RidDescription>& rids_desc);
101 
102     const std::string mid;
103     const cricket::MediaProtocolType media_protocol_type;
104     std::vector<std::string> rids;
105     cricket::SimulcastDescription simulcast_description;
106     webrtc::RtpExtension mid_extension;
107     webrtc::RtpExtension rid_extension;
108     webrtc::RtpExtension rrid_extension;
109     cricket::TransportDescription transport_description;
110   };
111 
112   struct SignalingContext {
113     SignalingContext() = default;
114     // SignalingContext is not copyable and movable.
115     SignalingContext(SignalingContext&) = delete;
116     SignalingContext& operator=(SignalingContext&) = delete;
117     SignalingContext(SignalingContext&&) = delete;
118     SignalingContext& operator=(SignalingContext&&) = delete;
119 
120     void AddSimulcastInfo(const SimulcastSectionInfo& info);
HasSimulcastSignalingContext121     bool HasSimulcast() const { return !simulcast_infos.empty(); }
122 
123     std::vector<SimulcastSectionInfo> simulcast_infos;
124     std::map<std::string, SimulcastSectionInfo*> simulcast_infos_by_mid;
125     std::map<std::string, SimulcastSectionInfo*> simulcast_infos_by_rid;
126 
127     std::vector<std::string> mids_order;
128   };
129 
130   LocalAndRemoteSdp PatchVp8Offer(
131       std::unique_ptr<SessionDescriptionInterface> offer);
132   LocalAndRemoteSdp PatchVp9Offer(
133       std::unique_ptr<SessionDescriptionInterface> offer);
134   LocalAndRemoteSdp PatchVp8Answer(
135       std::unique_ptr<SessionDescriptionInterface> offer);
136   LocalAndRemoteSdp PatchVp9Answer(
137       std::unique_ptr<SessionDescriptionInterface> offer);
138 
139   void FillSimulcastContext(SessionDescriptionInterface* offer);
140   std::unique_ptr<cricket::SessionDescription> RestoreMediaSectionsOrder(
141       std::unique_ptr<cricket::SessionDescription> source);
142 
143   PatchingParams params_;
144   SignalingContext context_;
145 };
146 
147 }  // namespace webrtc_pc_e2e
148 }  // namespace webrtc
149 
150 #endif  // TEST_PC_E2E_SDP_SDP_CHANGER_H_
151