Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2014 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/audio_coding/main/test/PacketLossTest.h"
     12 
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 #include "webrtc/common.h"
     15 #include "webrtc/test/testsupport/fileutils.h"
     16 
     17 namespace webrtc {
     18 
     19 ReceiverWithPacketLoss::ReceiverWithPacketLoss()
     20     : loss_rate_(0),
     21       burst_length_(1),
     22       packet_counter_(0),
     23       lost_packet_counter_(0),
     24       burst_lost_counter_(burst_length_) {
     25 }
     26 
     27 void ReceiverWithPacketLoss::Setup(AudioCodingModule *acm,
     28                                    RTPStream *rtpStream,
     29                                    std::string out_file_name,
     30                                    int channels,
     31                                    int loss_rate,
     32                                    int burst_length) {
     33   loss_rate_ = loss_rate;
     34   burst_length_ = burst_length;
     35   burst_lost_counter_ = burst_length_;  // To prevent first packet gets lost.
     36   std::stringstream ss;
     37   ss << out_file_name << "_" << loss_rate_ << "_" << burst_length_ << "_";
     38   Receiver::Setup(acm, rtpStream, ss.str(), channels);
     39 }
     40 
     41 bool ReceiverWithPacketLoss::IncomingPacket() {
     42   if (!_rtpStream->EndOfFile()) {
     43     if (packet_counter_ == 0) {
     44       _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload,
     45                                                _payloadSizeBytes, &_nextTime);
     46       if (_realPayloadSizeBytes == 0) {
     47         if (_rtpStream->EndOfFile()) {
     48           packet_counter_ = 0;
     49           return true;
     50         } else {
     51           return false;
     52         }
     53       }
     54     }
     55 
     56     if (!PacketLost()) {
     57       _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, _rtpInfo);
     58     }
     59     packet_counter_++;
     60     _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload,
     61                                              _payloadSizeBytes, &_nextTime);
     62     if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
     63       packet_counter_ = 0;
     64       lost_packet_counter_ = 0;
     65     }
     66   }
     67   return true;
     68 }
     69 
     70 bool ReceiverWithPacketLoss::PacketLost() {
     71   if (burst_lost_counter_ < burst_length_) {
     72     lost_packet_counter_++;
     73     burst_lost_counter_++;
     74     return true;
     75   }
     76 
     77   if (lost_packet_counter_ * 100 < loss_rate_ * packet_counter_) {
     78     lost_packet_counter_++;
     79     burst_lost_counter_ = 1;
     80     return true;
     81   }
     82   return false;
     83 }
     84 
     85 SenderWithFEC::SenderWithFEC()
     86     : expected_loss_rate_(0) {
     87 }
     88 
     89 void SenderWithFEC::Setup(AudioCodingModule *acm, RTPStream *rtpStream,
     90                           std::string in_file_name, int sample_rate,
     91                           int channels, int expected_loss_rate) {
     92   Sender::Setup(acm, rtpStream, in_file_name, sample_rate, channels);
     93   EXPECT_TRUE(SetFEC(true));
     94   EXPECT_TRUE(SetPacketLossRate(expected_loss_rate));
     95 }
     96 
     97 bool SenderWithFEC::SetFEC(bool enable_fec) {
     98   if (_acm->SetCodecFEC(enable_fec) == 0) {
     99     return true;
    100   }
    101   return false;
    102 }
    103 
    104 bool SenderWithFEC::SetPacketLossRate(int expected_loss_rate) {
    105   if (_acm->SetPacketLossRate(expected_loss_rate) == 0) {
    106     expected_loss_rate_ = expected_loss_rate;
    107     return true;
    108   }
    109   return false;
    110 }
    111 
    112 PacketLossTest::PacketLossTest(int channels, int expected_loss_rate,
    113                                int actual_loss_rate, int burst_length)
    114     : channels_(channels),
    115       in_file_name_(channels_ == 1 ? "audio_coding/testfile32kHz" :
    116                     "audio_coding/teststereo32kHz"),
    117       sample_rate_hz_(32000),
    118       sender_(new SenderWithFEC),
    119       receiver_(new ReceiverWithPacketLoss),
    120       expected_loss_rate_(expected_loss_rate),
    121       actual_loss_rate_(actual_loss_rate),
    122       burst_length_(burst_length) {
    123 }
    124 
    125 void PacketLossTest::Perform() {
    126 #ifndef WEBRTC_CODEC_OPUS
    127   return;
    128 #else
    129   scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(0));
    130 
    131   int codec_id = acm->Codec("opus", 48000, channels_);
    132 
    133   RTPFile rtpFile;
    134   std::string fileName = webrtc::test::OutputPath() + "outFile.rtp";
    135 
    136   // Encode to file
    137   rtpFile.Open(fileName.c_str(), "wb+");
    138   rtpFile.WriteHeader();
    139 
    140   sender_->testMode = 0;
    141   sender_->codeId = codec_id;
    142 
    143   sender_->Setup(acm.get(), &rtpFile, in_file_name_, sample_rate_hz_, channels_,
    144                  expected_loss_rate_);
    145   struct CodecInst sendCodecInst;
    146   if (acm->SendCodec(&sendCodecInst) >= 0) {
    147     sender_->Run();
    148   }
    149   sender_->Teardown();
    150   rtpFile.Close();
    151 
    152   // Decode to file
    153   rtpFile.Open(fileName.c_str(), "rb");
    154   rtpFile.ReadHeader();
    155 
    156   receiver_->testMode = 0;
    157   receiver_->codeId = codec_id;
    158 
    159   receiver_->Setup(acm.get(), &rtpFile, "packetLoss_out", channels_,
    160                    actual_loss_rate_, burst_length_);
    161   receiver_->Run();
    162   receiver_->Teardown();
    163   rtpFile.Close();
    164 #endif
    165 }
    166 
    167 }  // namespace webrtc
    168