1 /*
2 * Copyright (c) 2012 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 #include "webrtc/modules/video_coding/main/test/mt_test_common.h"
12
13 #include <math.h>
14
15 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
16 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
17 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
18 #include "webrtc/modules/utility/interface/rtp_dump.h"
19 #include "webrtc/system_wrappers/interface/clock.h"
20
21 namespace webrtc {
22
TransportCallback(Clock * clock,const char * filename)23 TransportCallback::TransportCallback(Clock* clock, const char* filename)
24 : RTPSendCompleteCallback(clock, filename) {
25 }
26
~TransportCallback()27 TransportCallback::~TransportCallback()
28 {
29 //
30 }
31
32 int
SendPacket(int channel,const void * data,int len)33 TransportCallback::SendPacket(int channel, const void *data, int len)
34 {
35 _sendCount++;
36 _totalSentLength += len;
37
38 if (_rtpDump != NULL)
39 {
40 if (_rtpDump->DumpPacket((const uint8_t*)data, len) != 0)
41 {
42 return -1;
43 }
44 }
45
46 bool transmitPacket = true;
47 // Off-line tests, don't drop first Key frame (approx.)
48 if (_sendCount > 20)
49 {
50 transmitPacket = PacketLoss();
51 }
52
53 Clock* clock = Clock::GetRealTimeClock();
54 int64_t now = clock->TimeInMilliseconds();
55 // Insert outgoing packet into list
56 if (transmitPacket)
57 {
58 RtpPacket* newPacket = new RtpPacket();
59 memcpy(newPacket->data, data, len);
60 newPacket->length = len;
61 // Simulate receive time = network delay + packet jitter
62 // simulated as a Normal distribution random variable with
63 // mean = networkDelay and variance = jitterVar
64 int32_t
65 simulatedDelay = (int32_t)NormalDist(_networkDelayMs,
66 sqrt(_jitterVar));
67 newPacket->receiveTime = now + simulatedDelay;
68 _rtpPackets.push_back(newPacket);
69 }
70 return 0;
71 }
72
73 int
TransportPackets()74 TransportCallback::TransportPackets()
75 {
76 // Are we ready to send packets to the receiver?
77 RtpPacket* packet = NULL;
78 Clock* clock = Clock::GetRealTimeClock();
79 int64_t now = clock->TimeInMilliseconds();
80
81 while (!_rtpPackets.empty())
82 {
83 // Take first packet in list
84 packet = _rtpPackets.front();
85 int64_t timeToReceive = packet->receiveTime - now;
86 if (timeToReceive > 0)
87 {
88 // No available packets to send
89 break;
90 }
91
92 _rtpPackets.pop_front();
93 // Send to receive side
94 RTPHeader header;
95 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
96 if (!parser->Parse(packet->data, packet->length, &header)) {
97 delete packet;
98 return -1;
99 }
100 PayloadUnion payload_specific;
101 if (!rtp_payload_registry_->GetPayloadSpecifics(
102 header.payloadType, &payload_specific)) {
103 return -1;
104 }
105 if (!rtp_receiver_->IncomingRtpPacket(header, packet->data,
106 packet->length, payload_specific,
107 true))
108 {
109 delete packet;
110 return -1;
111 }
112 delete packet;
113 packet = NULL;
114 }
115 return 0; // OK
116 }
117
118
119
VCMProcessingThread(void * obj)120 bool VCMProcessingThread(void* obj)
121 {
122 SharedRTPState* state = static_cast<SharedRTPState*>(obj);
123 if (state->_vcm.TimeUntilNextProcess() <= 0)
124 {
125 if (state->_vcm.Process() < 0)
126 {
127 return false;
128 }
129 }
130 return true;
131 }
132
133
VCMDecodeThread(void * obj)134 bool VCMDecodeThread(void* obj)
135 {
136 SharedRTPState* state = static_cast<SharedRTPState*>(obj);
137 state->_vcm.Decode();
138 return true;
139 }
140
TransportThread(void * obj)141 bool TransportThread(void *obj)
142 {
143 SharedTransportState* state = static_cast<SharedTransportState*>(obj);
144 state->_transport.TransportPackets();
145 return true;
146 }
147
148 } // namespace webrtc
149