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 21namespace webrtc { 22 23TransportCallback::TransportCallback(Clock* clock, const char* filename) 24 : RTPSendCompleteCallback(clock, filename) { 25} 26 27TransportCallback::~TransportCallback() 28{ 29 // 30} 31 32int 33TransportCallback::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 73int 74TransportCallback::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 120bool 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 134bool VCMDecodeThread(void* obj) 135{ 136 SharedRTPState* state = static_cast<SharedRTPState*>(obj); 137 state->_vcm.Decode(); 138 return true; 139} 140 141bool TransportThread(void *obj) 142{ 143 SharedTransportState* state = static_cast<SharedTransportState*>(obj); 144 state->_transport.TransportPackets(); 145 return true; 146} 147 148} // namespace webrtc 149