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 #ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_ 12 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_ 13 14 #include <fstream> 15 #include <memory> 16 17 #include "api/audio_codecs/builtin_audio_decoder_factory.h" 18 #include "api/neteq/neteq.h" 19 #include "modules/audio_coding/neteq/tools/audio_sink.h" 20 #include "modules/audio_coding/neteq/tools/input_audio_file.h" 21 #include "modules/audio_coding/neteq/tools/rtp_generator.h" 22 #include "system_wrappers/include/clock.h" 23 #include "test/gtest.h" 24 25 namespace webrtc { 26 namespace test { 27 28 enum LossModes { 29 kNoLoss, 30 kUniformLoss, 31 kGilbertElliotLoss, 32 kFixedLoss, 33 kLastLossMode 34 }; 35 36 class LossModel { 37 public: ~LossModel()38 virtual ~LossModel() {} 39 virtual bool Lost(int now_ms) = 0; 40 }; 41 42 class NoLoss : public LossModel { 43 public: 44 bool Lost(int now_ms) override; 45 }; 46 47 class UniformLoss : public LossModel { 48 public: 49 UniformLoss(double loss_rate); 50 bool Lost(int now_ms) override; set_loss_rate(double loss_rate)51 void set_loss_rate(double loss_rate) { loss_rate_ = loss_rate; } 52 53 private: 54 double loss_rate_; 55 }; 56 57 class GilbertElliotLoss : public LossModel { 58 public: 59 GilbertElliotLoss(double prob_trans_11, double prob_trans_01); 60 ~GilbertElliotLoss() override; 61 bool Lost(int now_ms) override; 62 63 private: 64 // Prob. of losing current packet, when previous packet is lost. 65 double prob_trans_11_; 66 // Prob. of losing current packet, when previous packet is not lost. 67 double prob_trans_01_; 68 bool lost_last_; 69 std::unique_ptr<UniformLoss> uniform_loss_model_; 70 }; 71 72 struct FixedLossEvent { 73 int start_ms; 74 int duration_ms; FixedLossEventFixedLossEvent75 FixedLossEvent(int start_ms, int duration_ms) 76 : start_ms(start_ms), duration_ms(duration_ms) {} 77 }; 78 79 struct FixedLossEventCmp { operatorFixedLossEventCmp80 bool operator()(const FixedLossEvent& l_event, 81 const FixedLossEvent& r_event) const { 82 return l_event.start_ms < r_event.start_ms; 83 } 84 }; 85 86 class FixedLossModel : public LossModel { 87 public: 88 FixedLossModel(std::set<FixedLossEvent, FixedLossEventCmp> loss_events); 89 ~FixedLossModel() override; 90 bool Lost(int now_ms) override; 91 92 private: 93 std::set<FixedLossEvent, FixedLossEventCmp> loss_events_; 94 std::set<FixedLossEvent, FixedLossEventCmp>::iterator loss_events_it_; 95 }; 96 97 class NetEqQualityTest : public ::testing::Test { 98 protected: 99 NetEqQualityTest( 100 int block_duration_ms, 101 int in_sampling_khz, 102 int out_sampling_khz, 103 const SdpAudioFormat& format, 104 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory = 105 webrtc::CreateBuiltinAudioDecoderFactory()); 106 ~NetEqQualityTest() override; 107 108 void SetUp() override; 109 110 // EncodeBlock(...) does the following: 111 // 1. encodes a block of audio, saved in |in_data| and has a length of 112 // |block_size_samples| (samples per channel), 113 // 2. save the bit stream to |payload| of |max_bytes| bytes in size, 114 // 3. returns the length of the payload (in bytes), 115 virtual int EncodeBlock(int16_t* in_data, 116 size_t block_size_samples, 117 rtc::Buffer* payload, 118 size_t max_bytes) = 0; 119 120 // PacketLost(...) determines weather a packet sent at an indicated time gets 121 // lost or not. 122 bool PacketLost(); 123 124 // DecodeBlock() decodes a block of audio using the payload stored in 125 // |payload_| with the length of |payload_size_bytes_| (bytes). The decoded 126 // audio is to be stored in |out_data_|. 127 int DecodeBlock(); 128 129 // Transmit() uses |rtp_generator_| to generate a packet and passes it to 130 // |neteq_|. 131 int Transmit(); 132 133 // Runs encoding / transmitting / decoding. 134 void Simulate(); 135 136 // Write to log file. Usage Log() << ... 137 std::ofstream& Log(); 138 139 SdpAudioFormat audio_format_; 140 const size_t channels_; 141 142 private: 143 int decoded_time_ms_; 144 int decodable_time_ms_; 145 double drift_factor_; 146 int packet_loss_rate_; 147 const int block_duration_ms_; 148 const int in_sampling_khz_; 149 const int out_sampling_khz_; 150 151 // Number of samples per channel in a frame. 152 const size_t in_size_samples_; 153 154 size_t payload_size_bytes_; 155 size_t max_payload_bytes_; 156 157 std::unique_ptr<InputAudioFile> in_file_; 158 std::unique_ptr<AudioSink> output_; 159 std::ofstream log_file_; 160 161 std::unique_ptr<RtpGenerator> rtp_generator_; 162 std::unique_ptr<NetEq> neteq_; 163 std::unique_ptr<LossModel> loss_model_; 164 165 std::unique_ptr<int16_t[]> in_data_; 166 rtc::Buffer payload_; 167 AudioFrame out_frame_; 168 RTPHeader rtp_header_; 169 170 size_t total_payload_size_bytes_; 171 }; 172 173 } // namespace test 174 } // namespace webrtc 175 176 #endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_ 177