Home | History | Annotate | Download | only in test
      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 
     23 TransportCallback::TransportCallback(Clock* clock, const char* filename)
     24     : RTPSendCompleteCallback(clock, filename) {
     25 }
     26 
     27 TransportCallback::~TransportCallback()
     28 {
     29     //
     30 }
     31 
     32 int
     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
     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 
    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 
    134 bool VCMDecodeThread(void* obj)
    135 {
    136     SharedRTPState* state = static_cast<SharedRTPState*>(obj);
    137     state->_vcm.Decode();
    138     return true;
    139 }
    140 
    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