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