• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~RtpRtcpObserver()28   virtual ~RtpRtcpObserver() {}
SendTransport()29   newapi::Transport* SendTransport() {
30     return &send_transport_;
31   }
32 
ReceiveTransport()33   newapi::Transport* ReceiveTransport() {
34     return &receive_transport_;
35   }
36 
SetReceivers(PacketReceiver * send_transport_receiver,PacketReceiver * receive_transport_receiver)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 
StopSending()43   void StopSending() {
44     send_transport_.StopSending();
45     receive_transport_.StopSending();
46   }
47 
Wait()48   virtual EventTypeWrapper Wait() {
49     EventTypeWrapper result = observation_complete_->Wait(timeout_ms_);
50     observation_complete_->Reset();
51     return result;
52   }
53 
54  protected:
RtpRtcpObserver(unsigned int event_timeout_ms,const FakeNetworkPipe::Config & configuration)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 
RtpRtcpObserver(unsigned int event_timeout_ms)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 
OnSendRtp(const uint8_t * packet,size_t length)93   virtual Action OnSendRtp(const uint8_t* packet, size_t length)
94       EXCLUSIVE_LOCKS_REQUIRED(crit_) {
95     return SEND_PACKET;
96   }
97 
OnSendRtcp(const uint8_t * packet,size_t length)98   virtual Action OnSendRtcp(const uint8_t* packet, size_t length)
99       EXCLUSIVE_LOCKS_REQUIRED(crit_) {
100     return SEND_PACKET;
101   }
102 
OnReceiveRtp(const uint8_t * packet,size_t length)103   virtual Action OnReceiveRtp(const uint8_t* packet, size_t length)
104       EXCLUSIVE_LOCKS_REQUIRED(crit_) {
105     return SEND_PACKET;
106   }
107 
OnReceiveRtcp(const uint8_t * packet,size_t length)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 
PacketTransport(CriticalSectionWrapper * lock,RtpRtcpObserver * observer,PacketTransportAction on_rtp,PacketTransportAction on_rtcp,const FakeNetworkPipe::Config & configuration)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:
SendRtp(const uint8_t * packet,size_t length)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 
SendRtcp(const uint8_t * packet,size_t length)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