1 /*
2  *  Copyright (c) 2013 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 #ifndef TEST_RTP_RTCP_OBSERVER_H_
11 #define TEST_RTP_RTCP_OBSERVER_H_
12 
13 #include <map>
14 #include <memory>
15 #include <vector>
16 
17 #include "modules/rtp_rtcp/include/rtp_header_parser.h"
18 #include "rtc_base/criticalsection.h"
19 #include "rtc_base/event.h"
20 #include "system_wrappers/include/field_trial.h"
21 #include "test/constants.h"
22 #include "test/direct_transport.h"
23 #include "test/gtest.h"
24 #include "typedefs.h"  // NOLINT(build/include)
25 #include "call/video_send_stream.h"
26 
27 namespace {
28 const int kShortTimeoutMs = 500;
29 }
30 
31 namespace webrtc {
32 namespace test {
33 
34 class PacketTransport;
35 class SingleThreadedTaskQueueForTesting;
36 
37 class RtpRtcpObserver {
38  public:
39   enum Action {
40     SEND_PACKET,
41     DROP_PACKET,
42   };
43 
~RtpRtcpObserver()44   virtual ~RtpRtcpObserver() {}
45 
Wait()46   virtual bool Wait() {
47     if (field_trial::IsEnabled("WebRTC-QuickPerfTest")) {
48       observation_complete_.Wait(kShortTimeoutMs);
49       return true;
50     }
51     return observation_complete_.Wait(timeout_ms_);
52   }
53 
OnSendRtp(const uint8_t * packet,size_t length)54   virtual Action OnSendRtp(const uint8_t* packet, size_t length) {
55     return SEND_PACKET;
56   }
57 
OnSendRtcp(const uint8_t * packet,size_t length)58   virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
59     return SEND_PACKET;
60   }
61 
OnReceiveRtp(const uint8_t * packet,size_t length)62   virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) {
63     return SEND_PACKET;
64   }
65 
OnReceiveRtcp(const uint8_t * packet,size_t length)66   virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) {
67     return SEND_PACKET;
68   }
69 
70  protected:
RtpRtcpObserver()71   RtpRtcpObserver() : RtpRtcpObserver(0) {}
RtpRtcpObserver(int event_timeout_ms)72   explicit RtpRtcpObserver(int event_timeout_ms)
73       : observation_complete_(false, false),
74         parser_(RtpHeaderParser::Create()),
75         timeout_ms_(event_timeout_ms) {
76     parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
77                                         kTOffsetExtensionId);
78     parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
79                                         kAbsSendTimeExtensionId);
80     parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
81                                         kTransportSequenceNumberExtensionId);
82   }
83 
84   rtc::Event observation_complete_;
85   const std::unique_ptr<RtpHeaderParser> parser_;
86 
87  private:
88   const int timeout_ms_;
89 };
90 
91 class PacketTransport : public test::DirectTransport {
92  public:
93   enum TransportType { kReceiver, kSender };
94 
PacketTransport(SingleThreadedTaskQueueForTesting * task_queue,Call * send_call,RtpRtcpObserver * observer,TransportType transport_type,const std::map<uint8_t,MediaType> & payload_type_map,const FakeNetworkPipe::Config & configuration)95   PacketTransport(SingleThreadedTaskQueueForTesting* task_queue,
96                   Call* send_call,
97                   RtpRtcpObserver* observer,
98                   TransportType transport_type,
99                   const std::map<uint8_t, MediaType>& payload_type_map,
100                   const FakeNetworkPipe::Config& configuration)
101       : test::DirectTransport(task_queue,
102                               configuration,
103                               send_call,
104                               payload_type_map),
105         observer_(observer),
106         transport_type_(transport_type) {}
107 
PacketTransport(SingleThreadedTaskQueueForTesting * task_queue,Call * send_call,RtpRtcpObserver * observer,TransportType transport_type,std::unique_ptr<FakeNetworkPipe> nw_pipe)108   PacketTransport(SingleThreadedTaskQueueForTesting* task_queue,
109                   Call* send_call, RtpRtcpObserver* observer,
110                   TransportType transport_type,
111                   std::unique_ptr<FakeNetworkPipe> nw_pipe)
112       : test::DirectTransport(task_queue, std::move(nw_pipe), send_call),
113         observer_(observer),
114         transport_type_(transport_type) {}
115 
116  private:
SendRtp(const uint8_t * packet,size_t length,const PacketOptions & options)117   bool SendRtp(const uint8_t* packet,
118                size_t length,
119                const PacketOptions& options) override {
120     EXPECT_FALSE(RtpHeaderParser::IsRtcp(packet, length));
121     RtpRtcpObserver::Action action;
122     {
123       if (transport_type_ == kSender) {
124         action = observer_->OnSendRtp(packet, length);
125       } else {
126         action = observer_->OnReceiveRtp(packet, length);
127       }
128     }
129     switch (action) {
130       case RtpRtcpObserver::DROP_PACKET:
131         // Drop packet silently.
132         return true;
133       case RtpRtcpObserver::SEND_PACKET:
134         return test::DirectTransport::SendRtp(packet, length, options);
135     }
136     return true;  // Will never happen, makes compiler happy.
137   }
138 
SendRtcp(const uint8_t * packet,size_t length)139   bool SendRtcp(const uint8_t* packet, size_t length) override {
140     EXPECT_TRUE(RtpHeaderParser::IsRtcp(packet, length));
141     RtpRtcpObserver::Action action;
142     {
143       if (transport_type_ == kSender) {
144         action = observer_->OnSendRtcp(packet, length);
145       } else {
146         action = observer_->OnReceiveRtcp(packet, length);
147       }
148     }
149     switch (action) {
150       case RtpRtcpObserver::DROP_PACKET:
151         // Drop packet silently.
152         return true;
153       case RtpRtcpObserver::SEND_PACKET:
154         return test::DirectTransport::SendRtcp(packet, length);
155     }
156     return true;  // Will never happen, makes compiler happy.
157   }
158 
159   RtpRtcpObserver* const observer_;
160   TransportType transport_type_;
161 };
162 }  // namespace test
163 }  // namespace webrtc
164 
165 #endif  // TEST_RTP_RTCP_OBSERVER_H_
166