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