• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 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 
11 #ifndef SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
12 #define SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
13 
14 #include <deque>
15 
16 #include "webrtc/base/platform_thread.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/common_types.h"
19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
20 #include "webrtc/system_wrappers/include/atomic32.h"
21 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
22 #include "webrtc/system_wrappers/include/event_wrapper.h"
23 #include "webrtc/system_wrappers/include/sleep.h"
24 #include "webrtc/voice_engine/test/auto_test/fixtures/before_initialization_fixture.h"
25 
26 class TestErrorObserver;
27 
28 class LoopBackTransport : public webrtc::Transport {
29  public:
LoopBackTransport(webrtc::VoENetwork * voe_network,int channel)30   LoopBackTransport(webrtc::VoENetwork* voe_network, int channel)
31       : crit_(webrtc::CriticalSectionWrapper::CreateCriticalSection()),
32         packet_event_(webrtc::EventWrapper::Create()),
33         thread_(NetworkProcess, this, "LoopBackTransport"),
34         channel_(channel),
35         voe_network_(voe_network),
36         transmitted_packets_(0) {
37     thread_.Start();
38   }
39 
~LoopBackTransport()40   ~LoopBackTransport() { thread_.Stop(); }
41 
SendRtp(const uint8_t * data,size_t len,const webrtc::PacketOptions & options)42   bool SendRtp(const uint8_t* data,
43                size_t len,
44                const webrtc::PacketOptions& options) override {
45     StorePacket(Packet::Rtp, data, len);
46     return true;
47   }
48 
SendRtcp(const uint8_t * data,size_t len)49   bool SendRtcp(const uint8_t* data, size_t len) override {
50     StorePacket(Packet::Rtcp, data, len);
51     return true;
52   }
53 
WaitForTransmittedPackets(int32_t packet_count)54   void WaitForTransmittedPackets(int32_t packet_count) {
55     enum {
56       kSleepIntervalMs = 10
57     };
58     int32_t limit = transmitted_packets_.Value() + packet_count;
59     while (transmitted_packets_.Value() < limit) {
60       webrtc::SleepMs(kSleepIntervalMs);
61     }
62   }
63 
AddChannel(uint32_t ssrc,int channel)64   void AddChannel(uint32_t ssrc, int channel) {
65     webrtc::CriticalSectionScoped lock(crit_.get());
66     channels_[ssrc] = channel;
67   }
68 
69  private:
70   struct Packet {
71     enum Type { Rtp, Rtcp, } type;
72 
PacketPacket73     Packet() : len(0) {}
PacketPacket74     Packet(Type type, const void* data, size_t len)
75         : type(type), len(len) {
76       assert(len <= 1500);
77       memcpy(this->data, data, len);
78     }
79 
80     uint8_t data[1500];
81     size_t len;
82   };
83 
StorePacket(Packet::Type type,const void * data,size_t len)84   void StorePacket(Packet::Type type,
85                    const void* data,
86                    size_t len) {
87     {
88       webrtc::CriticalSectionScoped lock(crit_.get());
89       packet_queue_.push_back(Packet(type, data, len));
90     }
91     packet_event_->Set();
92   }
93 
NetworkProcess(void * transport)94   static bool NetworkProcess(void* transport) {
95     return static_cast<LoopBackTransport*>(transport)->SendPackets();
96   }
97 
SendPackets()98   bool SendPackets() {
99     switch (packet_event_->Wait(10)) {
100       case webrtc::kEventSignaled:
101         break;
102       case webrtc::kEventTimeout:
103         break;
104       case webrtc::kEventError:
105         // TODO(pbos): Log a warning here?
106         return true;
107     }
108 
109     while (true) {
110       Packet p;
111       int channel = channel_;
112       {
113         webrtc::CriticalSectionScoped lock(crit_.get());
114         if (packet_queue_.empty())
115           break;
116         p = packet_queue_.front();
117         packet_queue_.pop_front();
118 
119         if (p.type == Packet::Rtp) {
120           uint32_t ssrc =
121               webrtc::ByteReader<uint32_t>::ReadBigEndian(&p.data[8]);
122           if (channels_[ssrc] != 0)
123             channel = channels_[ssrc];
124         }
125         // TODO(pbos): Add RTCP SSRC muxing/demuxing if anything requires it.
126       }
127 
128       // Minimum RTP header size.
129       if (p.len < 12)
130         continue;
131 
132       switch (p.type) {
133         case Packet::Rtp:
134           voe_network_->ReceivedRTPPacket(channel, p.data, p.len,
135                                           webrtc::PacketTime());
136           break;
137         case Packet::Rtcp:
138           voe_network_->ReceivedRTCPPacket(channel, p.data, p.len);
139           break;
140       }
141       ++transmitted_packets_;
142     }
143     return true;
144   }
145 
146   const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> crit_;
147   const rtc::scoped_ptr<webrtc::EventWrapper> packet_event_;
148   rtc::PlatformThread thread_;
149   std::deque<Packet> packet_queue_ GUARDED_BY(crit_.get());
150   const int channel_;
151   std::map<uint32_t, int> channels_ GUARDED_BY(crit_.get());
152   webrtc::VoENetwork* const voe_network_;
153   webrtc::Atomic32 transmitted_packets_;
154 };
155 
156 // This fixture initializes the voice engine in addition to the work
157 // done by the before-initialization fixture. It also registers an error
158 // observer which will fail tests on error callbacks. This fixture is
159 // useful to tests that want to run before we have started any form of
160 // streaming through the voice engine.
161 class AfterInitializationFixture : public BeforeInitializationFixture {
162  public:
163   AfterInitializationFixture();
164   virtual ~AfterInitializationFixture();
165 
166  protected:
167   rtc::scoped_ptr<TestErrorObserver> error_observer_;
168 };
169 
170 #endif  // SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
171