blob: 7b3ff2257000aed25793b2386c9604fe3d9e9084 [file] [log] [blame]
pbos@webrtc.org96684672013-08-12 12:59:04 +00001/*
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 */
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000010#include "webrtc/test/direct_transport.h"
pbos@webrtc.org96684672013-08-12 12:59:04 +000011
12#include "testing/gtest/include/gtest/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000013
14#include "webrtc/call.h"
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000015#include "webrtc/system_wrappers/interface/clock.h"
pbos@webrtc.org96684672013-08-12 12:59:04 +000016
17namespace webrtc {
18namespace test {
19
20DirectTransport::DirectTransport()
21 : lock_(CriticalSectionWrapper::CreateCriticalSection()),
22 packet_event_(EventWrapper::Create()),
23 thread_(ThreadWrapper::CreateThread(NetworkProcess, this)),
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000024 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.org468e19a2013-08-12 14:28:00 +000025 shutting_down_(false),
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000026 receiver_(NULL),
27 delay_ms_(0) {
28 unsigned int thread_id;
29 EXPECT_TRUE(thread_->Start(thread_id));
30}
31
32DirectTransport::DirectTransport(int delay_ms)
33 : lock_(CriticalSectionWrapper::CreateCriticalSection()),
34 packet_event_(EventWrapper::Create()),
35 thread_(ThreadWrapper::CreateThread(NetworkProcess, this)),
36 clock_(Clock::GetRealTimeClock()),
37 shutting_down_(false),
38 receiver_(NULL),
39 delay_ms_(delay_ms) {
pbos@webrtc.org96684672013-08-12 12:59:04 +000040 unsigned int thread_id;
41 EXPECT_TRUE(thread_->Start(thread_id));
42}
43
44DirectTransport::~DirectTransport() { StopSending(); }
45
pbos@webrtc.org468e19a2013-08-12 14:28:00 +000046void DirectTransport::StopSending() {
47 {
48 CriticalSectionScoped crit_(lock_.get());
49 shutting_down_ = true;
50 }
51
52 packet_event_->Set();
53 EXPECT_TRUE(thread_->Stop());
54}
pbos@webrtc.org96684672013-08-12 12:59:04 +000055
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000056void DirectTransport::SetReceiver(PacketReceiver* receiver) {
pbos@webrtc.org96684672013-08-12 12:59:04 +000057 receiver_ = receiver;
58}
59
pbos@webrtc.org27326b62013-11-20 12:17:04 +000060bool DirectTransport::SendRtp(const uint8_t* data, size_t length) {
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000061 QueuePacket(data, length, clock_->TimeInMilliseconds() + delay_ms_);
pbos@webrtc.org96684672013-08-12 12:59:04 +000062 return true;
63}
64
pbos@webrtc.org27326b62013-11-20 12:17:04 +000065bool DirectTransport::SendRtcp(const uint8_t* data, size_t length) {
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000066 QueuePacket(data, length, clock_->TimeInMilliseconds() + delay_ms_);
pbos@webrtc.org96684672013-08-12 12:59:04 +000067 return true;
68}
69
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000070DirectTransport::Packet::Packet() : length(0), delivery_time_ms(0) {}
pbos@webrtc.org96684672013-08-12 12:59:04 +000071
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000072DirectTransport::Packet::Packet(const uint8_t* data,
73 size_t length,
74 int64_t delivery_time_ms)
75 : length(length), delivery_time_ms(delivery_time_ms) {
pbos@webrtc.org96684672013-08-12 12:59:04 +000076 EXPECT_LE(length, sizeof(this->data));
77 memcpy(this->data, data, length);
78}
79
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000080void DirectTransport::QueuePacket(const uint8_t* data,
81 size_t length,
82 int64_t delivery_time_ms) {
pbos@webrtc.org96684672013-08-12 12:59:04 +000083 CriticalSectionScoped crit(lock_.get());
stefan@webrtc.org69969e22013-11-15 12:32:15 +000084 if (receiver_ == NULL)
85 return;
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000086 packet_queue_.push_back(Packet(data, length, delivery_time_ms));
pbos@webrtc.org96684672013-08-12 12:59:04 +000087 packet_event_->Set();
88}
89
90bool DirectTransport::NetworkProcess(void* transport) {
91 return static_cast<DirectTransport*>(transport)->SendPackets();
92}
93
94bool DirectTransport::SendPackets() {
95 while (true) {
96 Packet p;
97 {
pbos@webrtc.org468e19a2013-08-12 14:28:00 +000098 CriticalSectionScoped crit(lock_.get());
pbos@webrtc.org96684672013-08-12 12:59:04 +000099 if (packet_queue_.empty())
100 break;
101 p = packet_queue_.front();
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +0000102 if (p.delivery_time_ms > clock_->TimeInMilliseconds())
103 break;
pbos@webrtc.org96684672013-08-12 12:59:04 +0000104 packet_queue_.pop_front();
105 }
106 receiver_->DeliverPacket(p.data, p.length);
107 }
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +0000108 uint32_t time_until_next_delivery = WEBRTC_EVENT_INFINITE;
109 {
110 CriticalSectionScoped crit(lock_.get());
111 if (!packet_queue_.empty()) {
112 int64_t now_ms = clock_->TimeInMilliseconds();
113 const int64_t delivery_time_ms = packet_queue_.front().delivery_time_ms;
114 if (delivery_time_ms > now_ms) {
115 time_until_next_delivery = delivery_time_ms - now_ms;
116 } else {
117 time_until_next_delivery = 0;
118 }
119 }
120 }
pbos@webrtc.org96684672013-08-12 12:59:04 +0000121
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +0000122 switch (packet_event_->Wait(time_until_next_delivery)) {
pbos@webrtc.org96684672013-08-12 12:59:04 +0000123 case kEventSignaled:
124 packet_event_->Reset();
125 break;
126 case kEventTimeout:
127 break;
128 case kEventError:
129 // TODO(pbos): Log a warning here?
130 return true;
131 }
132
pbos@webrtc.org468e19a2013-08-12 14:28:00 +0000133 CriticalSectionScoped crit(lock_.get());
134 return shutting_down_ ? false : true;
pbos@webrtc.org96684672013-08-12 12:59:04 +0000135}
136} // namespace test
137} // namespace webrtc