Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc

Issue 1481493004: audio_coding: remove "main" directory (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2013 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 <stdio.h>
12
13 #include "gflags/gflags.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webrtc/base/scoped_ptr.h"
16 #include "webrtc/common_types.h"
17 #include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"
18 #include "webrtc/modules/audio_coding/main/test/Channel.h"
19 #include "webrtc/modules/audio_coding/main/test/PCMFile.h"
20 #include "webrtc/modules/include/module_common_types.h"
21 #include "webrtc/system_wrappers/include/clock.h"
22 #include "webrtc/test/testsupport/fileutils.h"
23
24 // Codec.
25 DEFINE_string(codec, "opus", "Codec Name");
26 DEFINE_int32(codec_sample_rate_hz, 48000, "Sampling rate in Hertz.");
27 DEFINE_int32(codec_channels, 1, "Number of channels of the codec.");
28
29 // PCM input/output.
30 DEFINE_string(input, "", "Input PCM file at 16 kHz.");
31 DEFINE_bool(input_stereo, false, "Input is stereo.");
32 DEFINE_int32(input_fs_hz, 32000, "Input sample rate Hz.");
33 DEFINE_string(output, "insert_rtp_with_timing_out.pcm", "OutputFile");
34 DEFINE_int32(output_fs_hz, 32000, "Output sample rate Hz");
35
36 // Timing files
37 DEFINE_string(seq_num, "seq_num", "Sequence number file.");
38 DEFINE_string(send_ts, "send_timestamp", "Send timestamp file.");
39 DEFINE_string(receive_ts, "last_rec_timestamp", "Receive timestamp file");
40
41 // Delay logging
42 DEFINE_string(delay, "", "Log for delay.");
43
44 // Other setups
45 DEFINE_bool(verbose, false, "Verbosity.");
46 DEFINE_double(loss_rate, 0, "Rate of packet loss < 1");
47
48 const int32_t kAudioPlayedOut = 0x00000001;
49 const int32_t kPacketPushedIn = 0x00000001 << 1;
50 const int kPlayoutPeriodMs = 10;
51
52 namespace webrtc {
53
54 class InsertPacketWithTiming {
55 public:
56 InsertPacketWithTiming()
57 : sender_clock_(new SimulatedClock(0)),
58 receiver_clock_(new SimulatedClock(0)),
59 send_acm_(AudioCodingModule::Create(0, sender_clock_)),
60 receive_acm_(AudioCodingModule::Create(0, receiver_clock_)),
61 channel_(new Channel),
62 seq_num_fid_(fopen(FLAGS_seq_num.c_str(), "rt")),
63 send_ts_fid_(fopen(FLAGS_send_ts.c_str(), "rt")),
64 receive_ts_fid_(fopen(FLAGS_receive_ts.c_str(), "rt")),
65 pcm_out_fid_(fopen(FLAGS_output.c_str(), "wb")),
66 samples_in_1ms_(48),
67 num_10ms_in_codec_frame_(2), // Typical 20 ms frames.
68 time_to_insert_packet_ms_(3), // An arbitrary offset on pushing packet.
69 next_receive_ts_(0),
70 time_to_playout_audio_ms_(kPlayoutPeriodMs),
71 loss_threshold_(0),
72 playout_timing_fid_(fopen("playout_timing.txt", "wt")) {}
73
74 void SetUp() {
75 ASSERT_TRUE(sender_clock_ != NULL);
76 ASSERT_TRUE(receiver_clock_ != NULL);
77
78 ASSERT_TRUE(send_acm_.get() != NULL);
79 ASSERT_TRUE(receive_acm_.get() != NULL);
80 ASSERT_TRUE(channel_ != NULL);
81
82 ASSERT_TRUE(seq_num_fid_ != NULL);
83 ASSERT_TRUE(send_ts_fid_ != NULL);
84 ASSERT_TRUE(receive_ts_fid_ != NULL);
85
86 ASSERT_TRUE(playout_timing_fid_ != NULL);
87
88 next_receive_ts_ = ReceiveTimestamp();
89
90 CodecInst codec;
91 ASSERT_EQ(0, AudioCodingModule::Codec(FLAGS_codec.c_str(), &codec,
92 FLAGS_codec_sample_rate_hz,
93 FLAGS_codec_channels));
94 ASSERT_EQ(0, receive_acm_->InitializeReceiver());
95 ASSERT_EQ(0, send_acm_->RegisterSendCodec(codec));
96 ASSERT_EQ(0, receive_acm_->RegisterReceiveCodec(codec));
97
98 // Set codec-dependent parameters.
99 samples_in_1ms_ = codec.plfreq / 1000;
100 num_10ms_in_codec_frame_ = codec.pacsize / (codec.plfreq / 100);
101
102 channel_->RegisterReceiverACM(receive_acm_.get());
103 send_acm_->RegisterTransportCallback(channel_);
104
105 if (FLAGS_input.size() == 0) {
106 std::string file_name = test::ResourcePath("audio_coding/testfile32kHz",
107 "pcm");
108 pcm_in_fid_.Open(file_name, 32000, "r", true); // auto-rewind
109 std::cout << "Input file " << file_name << " 32 kHz mono." << std::endl;
110 } else {
111 pcm_in_fid_.Open(FLAGS_input, static_cast<uint16_t>(FLAGS_input_fs_hz),
112 "r", true); // auto-rewind
113 std::cout << "Input file " << FLAGS_input << "at " << FLAGS_input_fs_hz
114 << " Hz in " << ((FLAGS_input_stereo) ? "stereo." : "mono.")
115 << std::endl;
116 pcm_in_fid_.ReadStereo(FLAGS_input_stereo);
117 }
118
119 ASSERT_TRUE(pcm_out_fid_ != NULL);
120 std::cout << "Output file " << FLAGS_output << " at " << FLAGS_output_fs_hz
121 << " Hz." << std::endl;
122
123 // Other setups
124 if (FLAGS_loss_rate > 0)
125 loss_threshold_ = RAND_MAX * FLAGS_loss_rate;
126 else
127 loss_threshold_ = 0;
128 }
129
130 void TickOneMillisecond(uint32_t* action) {
131 // One millisecond passed.
132 time_to_insert_packet_ms_--;
133 time_to_playout_audio_ms_--;
134 sender_clock_->AdvanceTimeMilliseconds(1);
135 receiver_clock_->AdvanceTimeMilliseconds(1);
136
137 // Reset action.
138 *action = 0;
139
140 // Is it time to pull audio?
141 if (time_to_playout_audio_ms_ == 0) {
142 time_to_playout_audio_ms_ = kPlayoutPeriodMs;
143 receive_acm_->PlayoutData10Ms(static_cast<int>(FLAGS_output_fs_hz),
144 &frame_);
145 fwrite(frame_.data_, sizeof(frame_.data_[0]),
146 frame_.samples_per_channel_ * frame_.num_channels_, pcm_out_fid_);
147 *action |= kAudioPlayedOut;
148 }
149
150 // Is it time to push in next packet?
151 if (time_to_insert_packet_ms_ <= .5) {
152 *action |= kPacketPushedIn;
153
154 // Update time-to-insert packet.
155 uint32_t t = next_receive_ts_;
156 next_receive_ts_ = ReceiveTimestamp();
157 time_to_insert_packet_ms_ += static_cast<float>(next_receive_ts_ - t) /
158 samples_in_1ms_;
159
160 // Push in just enough audio.
161 for (int n = 0; n < num_10ms_in_codec_frame_; n++) {
162 pcm_in_fid_.Read10MsData(frame_);
163 EXPECT_GE(send_acm_->Add10MsData(frame_), 0);
164 }
165
166 // Set the parameters for the packet to be pushed in receiver ACM right
167 // now.
168 uint32_t ts = SendTimestamp();
169 int seq_num = SequenceNumber();
170 bool lost = false;
171 channel_->set_send_timestamp(ts);
172 channel_->set_sequence_number(seq_num);
173 if (loss_threshold_ > 0 && rand() < loss_threshold_) {
174 channel_->set_num_packets_to_drop(1);
175 lost = true;
176 }
177
178 if (FLAGS_verbose) {
179 if (!lost) {
180 std::cout << "\nInserting packet number " << seq_num
181 << " timestamp " << ts << std::endl;
182 } else {
183 std::cout << "\nLost packet number " << seq_num
184 << " timestamp " << ts << std::endl;
185 }
186 }
187 }
188 }
189
190 void TearDown() {
191 delete channel_;
192
193 fclose(seq_num_fid_);
194 fclose(send_ts_fid_);
195 fclose(receive_ts_fid_);
196 fclose(pcm_out_fid_);
197 pcm_in_fid_.Close();
198 }
199
200 ~InsertPacketWithTiming() {
201 delete sender_clock_;
202 delete receiver_clock_;
203 }
204
205 // Are there more info to simulate.
206 bool HasPackets() {
207 if (feof(seq_num_fid_) || feof(send_ts_fid_) || feof(receive_ts_fid_))
208 return false;
209 return true;
210 }
211
212 // Jitter buffer delay.
213 void Delay(int* optimal_delay, int* current_delay) {
214 NetworkStatistics statistics;
215 receive_acm_->GetNetworkStatistics(&statistics);
216 *optimal_delay = statistics.preferredBufferSize;
217 *current_delay = statistics.currentBufferSize;
218 }
219
220 private:
221 uint32_t SendTimestamp() {
222 uint32_t t;
223 EXPECT_EQ(1, fscanf(send_ts_fid_, "%u\n", &t));
224 return t;
225 }
226
227 uint32_t ReceiveTimestamp() {
228 uint32_t t;
229 EXPECT_EQ(1, fscanf(receive_ts_fid_, "%u\n", &t));
230 return t;
231 }
232
233 int SequenceNumber() {
234 int n;
235 EXPECT_EQ(1, fscanf(seq_num_fid_, "%d\n", &n));
236 return n;
237 }
238
239 // This class just creates these pointers, not deleting them. They are deleted
240 // by the associated ACM.
241 SimulatedClock* sender_clock_;
242 SimulatedClock* receiver_clock_;
243
244 rtc::scoped_ptr<AudioCodingModule> send_acm_;
245 rtc::scoped_ptr<AudioCodingModule> receive_acm_;
246 Channel* channel_;
247
248 FILE* seq_num_fid_; // Input (text), one sequence number per line.
249 FILE* send_ts_fid_; // Input (text), one send timestamp per line.
250 FILE* receive_ts_fid_; // Input (text), one receive timestamp per line.
251 FILE* pcm_out_fid_; // Output PCM16.
252
253 PCMFile pcm_in_fid_; // Input PCM16.
254
255 int samples_in_1ms_;
256
257 // TODO(turajs): this can be computed from the send timestamp, but there is
258 // some complication to account for lost and reordered packets.
259 int num_10ms_in_codec_frame_;
260
261 float time_to_insert_packet_ms_;
262 uint32_t next_receive_ts_;
263 uint32_t time_to_playout_audio_ms_;
264
265 AudioFrame frame_;
266
267 double loss_threshold_;
268
269 // Output (text), sequence number, playout timestamp, time (ms) of playout,
270 // per line.
271 FILE* playout_timing_fid_;
272 };
273
274 } // webrtc
275
276 int main(int argc, char* argv[]) {
277 google::ParseCommandLineFlags(&argc, &argv, true);
278 webrtc::InsertPacketWithTiming test;
279 test.SetUp();
280
281 FILE* delay_log = NULL;
282 if (FLAGS_delay.size() > 0) {
283 delay_log = fopen(FLAGS_delay.c_str(), "wt");
284 if (delay_log == NULL) {
285 std::cout << "Cannot open the file to log delay values." << std::endl;
286 exit(1);
287 }
288 }
289
290 uint32_t action_taken;
291 int optimal_delay_ms;
292 int current_delay_ms;
293 while (test.HasPackets()) {
294 test.TickOneMillisecond(&action_taken);
295
296 if (action_taken != 0) {
297 test.Delay(&optimal_delay_ms, &current_delay_ms);
298 if (delay_log != NULL) {
299 fprintf(delay_log, "%3d %3d\n", optimal_delay_ms, current_delay_ms);
300 }
301 }
302 }
303 std::cout << std::endl;
304 test.TearDown();
305 if (delay_log != NULL)
306 fclose(delay_log);
307 }
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/test/iSACTest.cc ('k') | webrtc/modules/audio_coding/main/test/opus_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698