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