• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "modules/rtp_rtcp/source/rtp_utility.h"
12 #include "pc/media_session.h"
13 #include "pc/session_description.h"
14 #include "test/field_trial.h"
15 #include "test/gtest.h"
16 #include "test/peer_scenario/peer_scenario.h"
17 
18 namespace webrtc {
19 namespace test {
20 namespace {
AudioExtensions(const SessionDescriptionInterface & session)21 RtpHeaderExtensionMap AudioExtensions(
22     const SessionDescriptionInterface& session) {
23   auto* audio_desc =
24       cricket::GetFirstAudioContentDescription(session.description());
25   return RtpHeaderExtensionMap(audio_desc->rtp_header_extensions());
26 }
27 
GetRtpPacketExtensions(const rtc::ArrayView<const uint8_t> packet,const RtpHeaderExtensionMap & extension_map)28 absl::optional<RTPHeaderExtension> GetRtpPacketExtensions(
29     const rtc::ArrayView<const uint8_t> packet,
30     const RtpHeaderExtensionMap& extension_map) {
31   RtpUtility::RtpHeaderParser rtp_parser(packet.data(), packet.size());
32   if (!rtp_parser.RTCP()) {
33     RTPHeader header;
34     if (rtp_parser.Parse(&header, &extension_map, true)) {
35       return header.extension;
36     }
37   }
38   return absl::nullopt;
39 }
40 
41 }  // namespace
42 
TEST(RemoteEstimateEndToEnd,OfferedCapabilityIsInAnswer)43 TEST(RemoteEstimateEndToEnd, OfferedCapabilityIsInAnswer) {
44   PeerScenario s(*test_info_);
45 
46   auto* caller = s.CreateClient(PeerScenarioClient::Config());
47   auto* callee = s.CreateClient(PeerScenarioClient::Config());
48 
49   auto send_link = {s.net()->NodeBuilder().Build().node};
50   auto ret_link = {s.net()->NodeBuilder().Build().node};
51 
52   s.net()->CreateRoute(caller->endpoint(), send_link, callee->endpoint());
53   s.net()->CreateRoute(callee->endpoint(), ret_link, caller->endpoint());
54 
55   auto signaling = s.ConnectSignaling(caller, callee, send_link, ret_link);
56   caller->CreateVideo("VIDEO", PeerScenarioClient::VideoSendTrackConfig());
57   std::atomic<bool> offer_exchange_done(false);
58   signaling.NegotiateSdp(
59       [](SessionDescriptionInterface* offer) {
60         for (auto& cont : offer->description()->contents()) {
61           cont.media_description()->set_remote_estimate(true);
62         }
63       },
64       [&](const SessionDescriptionInterface& answer) {
65         for (auto& cont : answer.description()->contents()) {
66           EXPECT_TRUE(cont.media_description()->remote_estimate());
67         }
68         offer_exchange_done = true;
69       });
70   RTC_CHECK(s.WaitAndProcess(&offer_exchange_done));
71 }
72 
TEST(RemoteEstimateEndToEnd,AudioUsesAbsSendTimeExtension)73 TEST(RemoteEstimateEndToEnd, AudioUsesAbsSendTimeExtension) {
74   // Defined before PeerScenario so it gets destructed after, to avoid use after free.
75   std::atomic<bool> received_abs_send_time(false);
76   PeerScenario s(*test_info_);
77 
78   auto* caller = s.CreateClient(PeerScenarioClient::Config());
79   auto* callee = s.CreateClient(PeerScenarioClient::Config());
80 
81   auto send_node = s.net()->NodeBuilder().Build().node;
82   auto ret_node = s.net()->NodeBuilder().Build().node;
83 
84   s.net()->CreateRoute(caller->endpoint(), {send_node}, callee->endpoint());
85   s.net()->CreateRoute(callee->endpoint(), {ret_node}, caller->endpoint());
86 
87   auto signaling = s.ConnectSignaling(caller, callee, {send_node}, {ret_node});
88   caller->CreateAudio("AUDIO", cricket::AudioOptions());
89   signaling.StartIceSignaling();
90   RtpHeaderExtensionMap extension_map;
91   std::atomic<bool> offer_exchange_done(false);
92   signaling.NegotiateSdp(
93       [&extension_map](SessionDescriptionInterface* offer) {
94         extension_map = AudioExtensions(*offer);
95         EXPECT_TRUE(extension_map.IsRegistered(kRtpExtensionAbsoluteSendTime));
96       },
97       [&](const SessionDescriptionInterface& answer) {
98         EXPECT_TRUE(AudioExtensions(answer).IsRegistered(
99             kRtpExtensionAbsoluteSendTime));
100         offer_exchange_done = true;
101       });
102   RTC_CHECK(s.WaitAndProcess(&offer_exchange_done));
103   send_node->router()->SetWatcher(
104       [extension_map, &received_abs_send_time](const EmulatedIpPacket& packet) {
105         // The dummy packets used by the fake signaling are filled with 0. We
106         // want to ignore those and we can do that on the basis that the first
107         // byte of RTP packets are guaranteed to not be 0.
108         // TODO(srte): Find a more elegant way to check for RTP traffic.
109         if (packet.size() > 1 && packet.cdata()[0] != 0) {
110           auto extensions = GetRtpPacketExtensions(packet.data, extension_map);
111           if (extensions) {
112             EXPECT_TRUE(extensions->hasAbsoluteSendTime);
113             received_abs_send_time = true;
114           }
115         }
116       });
117   RTC_CHECK(s.WaitAndProcess(&received_abs_send_time));
118 }
119 }  // namespace test
120 }  // namespace webrtc
121