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 WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ 11 #define WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ 12 13 #include <map> 14 #include <vector> 15 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 19 #include "webrtc/test/direct_transport.h" 20 #include "webrtc/typedefs.h" 21 #include "webrtc/video_send_stream.h" 22 23 namespace webrtc { 24 namespace test { 25 26 class RtpRtcpObserver { 27 public: 28 virtual ~RtpRtcpObserver() {} 29 newapi::Transport* SendTransport() { 30 return &send_transport_; 31 } 32 33 newapi::Transport* ReceiveTransport() { 34 return &receive_transport_; 35 } 36 37 virtual void SetReceivers(PacketReceiver* send_transport_receiver, 38 PacketReceiver* receive_transport_receiver) { 39 send_transport_.SetReceiver(send_transport_receiver); 40 receive_transport_.SetReceiver(receive_transport_receiver); 41 } 42 43 void StopSending() { 44 send_transport_.StopSending(); 45 receive_transport_.StopSending(); 46 } 47 48 virtual EventTypeWrapper Wait() { 49 EventTypeWrapper result = observation_complete_->Wait(timeout_ms_); 50 observation_complete_->Reset(); 51 return result; 52 } 53 54 protected: 55 RtpRtcpObserver(unsigned int event_timeout_ms, 56 const FakeNetworkPipe::Config& configuration) 57 : crit_(CriticalSectionWrapper::CreateCriticalSection()), 58 observation_complete_(EventWrapper::Create()), 59 parser_(RtpHeaderParser::Create()), 60 send_transport_(crit_.get(), 61 this, 62 &RtpRtcpObserver::OnSendRtp, 63 &RtpRtcpObserver::OnSendRtcp, 64 configuration), 65 receive_transport_(crit_.get(), 66 this, 67 &RtpRtcpObserver::OnReceiveRtp, 68 &RtpRtcpObserver::OnReceiveRtcp, 69 configuration), 70 timeout_ms_(event_timeout_ms) {} 71 72 explicit RtpRtcpObserver(unsigned int event_timeout_ms) 73 : crit_(CriticalSectionWrapper::CreateCriticalSection()), 74 observation_complete_(EventWrapper::Create()), 75 parser_(RtpHeaderParser::Create()), 76 send_transport_(crit_.get(), 77 this, 78 &RtpRtcpObserver::OnSendRtp, 79 &RtpRtcpObserver::OnSendRtcp, 80 FakeNetworkPipe::Config()), 81 receive_transport_(crit_.get(), 82 this, 83 &RtpRtcpObserver::OnReceiveRtp, 84 &RtpRtcpObserver::OnReceiveRtcp, 85 FakeNetworkPipe::Config()), 86 timeout_ms_(event_timeout_ms) {} 87 88 enum Action { 89 SEND_PACKET, 90 DROP_PACKET, 91 }; 92 93 virtual Action OnSendRtp(const uint8_t* packet, size_t length) 94 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 95 return SEND_PACKET; 96 } 97 98 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) 99 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 100 return SEND_PACKET; 101 } 102 103 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) 104 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 105 return SEND_PACKET; 106 } 107 108 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) 109 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 110 return SEND_PACKET; 111 } 112 113 private: 114 class PacketTransport : public test::DirectTransport { 115 public: 116 typedef Action (RtpRtcpObserver::*PacketTransportAction)(const uint8_t*, 117 size_t); 118 119 PacketTransport(CriticalSectionWrapper* lock, 120 RtpRtcpObserver* observer, 121 PacketTransportAction on_rtp, 122 PacketTransportAction on_rtcp, 123 const FakeNetworkPipe::Config& configuration) 124 : test::DirectTransport(configuration), 125 crit_(lock), 126 observer_(observer), 127 on_rtp_(on_rtp), 128 on_rtcp_(on_rtcp) {} 129 130 private: 131 virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE { 132 EXPECT_FALSE(RtpHeaderParser::IsRtcp(packet, length)); 133 Action action; 134 { 135 CriticalSectionScoped lock(crit_); 136 action = (observer_->*on_rtp_)(packet, length); 137 } 138 switch (action) { 139 case DROP_PACKET: 140 // Drop packet silently. 141 return true; 142 case SEND_PACKET: 143 return test::DirectTransport::SendRtp(packet, length); 144 } 145 return true; // Will never happen, makes compiler happy. 146 } 147 148 virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 149 EXPECT_TRUE(RtpHeaderParser::IsRtcp(packet, length)); 150 Action action; 151 { 152 CriticalSectionScoped lock(crit_); 153 action = (observer_->*on_rtcp_)(packet, length); 154 } 155 switch (action) { 156 case DROP_PACKET: 157 // Drop packet silently. 158 return true; 159 case SEND_PACKET: 160 return test::DirectTransport::SendRtcp(packet, length); 161 } 162 return true; // Will never happen, makes compiler happy. 163 } 164 165 // Pointer to shared lock instance protecting on_rtp_/on_rtcp_ calls. 166 CriticalSectionWrapper* const crit_; 167 168 RtpRtcpObserver* const observer_; 169 const PacketTransportAction on_rtp_, on_rtcp_; 170 }; 171 172 protected: 173 const scoped_ptr<CriticalSectionWrapper> crit_; 174 const scoped_ptr<EventWrapper> observation_complete_; 175 const scoped_ptr<RtpHeaderParser> parser_; 176 177 private: 178 PacketTransport send_transport_, receive_transport_; 179 unsigned int timeout_ms_; 180 }; 181 } // namespace test 182 } // namespace webrtc 183 184 #endif // WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ 185