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