• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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