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