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 <utility> 16 #include <vector> 17 18 #include "api/array_view.h" 19 #include "api/test/simulated_network.h" 20 #include "api/units/time_delta.h" 21 #include "call/simulated_packet_receiver.h" 22 #include "call/video_send_stream.h" 23 #include "modules/rtp_rtcp/source/rtp_util.h" 24 #include "rtc_base/event.h" 25 #include "system_wrappers/include/field_trial.h" 26 #include "test/direct_transport.h" 27 #include "test/gtest.h" 28 29 namespace { 30 constexpr webrtc::TimeDelta kShortTimeout = webrtc::TimeDelta::Millis(500); 31 } 32 33 namespace webrtc { 34 namespace test { 35 36 class PacketTransport; 37 38 class RtpRtcpObserver { 39 public: 40 enum Action { 41 SEND_PACKET, 42 DROP_PACKET, 43 }; 44 ~RtpRtcpObserver()45 virtual ~RtpRtcpObserver() {} 46 Wait()47 virtual bool Wait() { 48 if (field_trial::IsEnabled("WebRTC-QuickPerfTest")) { 49 observation_complete_.Wait(kShortTimeout); 50 return true; 51 } 52 return observation_complete_.Wait(timeout_); 53 } 54 OnSendRtp(const uint8_t * packet,size_t length)55 virtual Action OnSendRtp(const uint8_t* packet, size_t length) { 56 return SEND_PACKET; 57 } 58 OnSendRtcp(const uint8_t * packet,size_t length)59 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) { 60 return SEND_PACKET; 61 } 62 OnReceiveRtp(const uint8_t * packet,size_t length)63 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) { 64 return SEND_PACKET; 65 } 66 OnReceiveRtcp(const uint8_t * packet,size_t length)67 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) { 68 return SEND_PACKET; 69 } 70 71 protected: RtpRtcpObserver()72 RtpRtcpObserver() : RtpRtcpObserver(TimeDelta::Zero()) {} RtpRtcpObserver(TimeDelta event_timeout)73 explicit RtpRtcpObserver(TimeDelta event_timeout) : timeout_(event_timeout) {} 74 75 rtc::Event observation_complete_; 76 77 private: 78 const TimeDelta timeout_; 79 }; 80 81 class PacketTransport : public test::DirectTransport { 82 public: 83 enum TransportType { kReceiver, kSender }; 84 PacketTransport(TaskQueueBase * task_queue,Call * send_call,RtpRtcpObserver * observer,TransportType transport_type,const std::map<uint8_t,MediaType> & payload_type_map,std::unique_ptr<SimulatedPacketReceiverInterface> nw_pipe)85 PacketTransport(TaskQueueBase* task_queue, 86 Call* send_call, 87 RtpRtcpObserver* observer, 88 TransportType transport_type, 89 const std::map<uint8_t, MediaType>& payload_type_map, 90 std::unique_ptr<SimulatedPacketReceiverInterface> nw_pipe) 91 : test::DirectTransport(task_queue, 92 std::move(nw_pipe), 93 send_call, 94 payload_type_map), 95 observer_(observer), 96 transport_type_(transport_type) {} 97 98 private: SendRtp(const uint8_t * packet,size_t length,const PacketOptions & options)99 bool SendRtp(const uint8_t* packet, 100 size_t length, 101 const PacketOptions& options) override { 102 EXPECT_TRUE(IsRtpPacket(rtc::MakeArrayView(packet, length))); 103 RtpRtcpObserver::Action action; 104 { 105 if (transport_type_ == kSender) { 106 action = observer_->OnSendRtp(packet, length); 107 } else { 108 action = observer_->OnReceiveRtp(packet, length); 109 } 110 } 111 switch (action) { 112 case RtpRtcpObserver::DROP_PACKET: 113 // Drop packet silently. 114 return true; 115 case RtpRtcpObserver::SEND_PACKET: 116 return test::DirectTransport::SendRtp(packet, length, options); 117 } 118 return true; // Will never happen, makes compiler happy. 119 } 120 SendRtcp(const uint8_t * packet,size_t length)121 bool SendRtcp(const uint8_t* packet, size_t length) override { 122 EXPECT_TRUE(IsRtcpPacket(rtc::MakeArrayView(packet, length))); 123 RtpRtcpObserver::Action action; 124 { 125 if (transport_type_ == kSender) { 126 action = observer_->OnSendRtcp(packet, length); 127 } else { 128 action = observer_->OnReceiveRtcp(packet, length); 129 } 130 } 131 switch (action) { 132 case RtpRtcpObserver::DROP_PACKET: 133 // Drop packet silently. 134 return true; 135 case RtpRtcpObserver::SEND_PACKET: 136 return test::DirectTransport::SendRtcp(packet, length); 137 } 138 return true; // Will never happen, makes compiler happy. 139 } 140 141 RtpRtcpObserver* const observer_; 142 TransportType transport_type_; 143 }; 144 } // namespace test 145 } // namespace webrtc 146 147 #endif // TEST_RTP_RTCP_OBSERVER_H_ 148