blob: e2bed562c2b8e00195403a9985eaf0fe813b205f [file] [log] [blame]
henrik.lundine8a77e32016-06-22 06:34:03 -07001/*
2 * Copyright (c) 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/neteq/tools/neteq_test.h"
henrik.lundine8a77e32016-06-22 06:34:03 -070012
13#include <iostream>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
henrik.lundine8a77e32016-06-22 06:34:03 -070016
17namespace webrtc {
18namespace test {
19
20void DefaultNetEqTestErrorCallback::OnInsertPacketError(
henrik.lundine8a77e32016-06-22 06:34:03 -070021 const NetEqInput::PacketData& packet) {
Henrik Lundinc417d9e2017-06-14 12:29:03 +020022 std::cerr << "InsertPacket returned an error." << std::endl;
henrik.lundin7a38fd22017-04-28 01:35:53 -070023 std::cerr << "Packet data: " << packet.ToString() << std::endl;
henrik.lundine8a77e32016-06-22 06:34:03 -070024 FATAL();
25}
26
Henrik Lundinc417d9e2017-06-14 12:29:03 +020027void DefaultNetEqTestErrorCallback::OnGetAudioError() {
28 std::cerr << "GetAudio returned an error." << std::endl;
henrik.lundine8a77e32016-06-22 06:34:03 -070029 FATAL();
30}
31
32NetEqTest::NetEqTest(const NetEq::Config& config,
33 const DecoderMap& codecs,
34 const ExtDecoderMap& ext_codecs,
35 std::unique_ptr<NetEqInput> input,
36 std::unique_ptr<AudioSink> output,
henrik.lundin02739d92017-05-04 06:09:06 -070037 Callbacks callbacks)
henrik.lundine8a77e32016-06-22 06:34:03 -070038 : neteq_(NetEq::Create(config, CreateBuiltinAudioDecoderFactory())),
39 input_(std::move(input)),
40 output_(std::move(output)),
henrik.lundin02739d92017-05-04 06:09:06 -070041 callbacks_(callbacks),
henrik.lundine8a77e32016-06-22 06:34:03 -070042 sample_rate_hz_(config.sample_rate_hz) {
43 RTC_CHECK(!config.enable_muted_state)
44 << "The code does not handle enable_muted_state";
45 RegisterDecoders(codecs);
46 RegisterExternalDecoders(ext_codecs);
47}
48
49int64_t NetEqTest::Run() {
50 const int64_t start_time_ms = *input_->NextEventTime();
51 int64_t time_now_ms = start_time_ms;
52
53 while (!input_->ended()) {
54 // Advance time to next event.
55 RTC_DCHECK(input_->NextEventTime());
56 time_now_ms = *input_->NextEventTime();
57 // Check if it is time to insert packet.
58 if (input_->NextPacketTime() && time_now_ms >= *input_->NextPacketTime()) {
59 std::unique_ptr<NetEqInput::PacketData> packet_data = input_->PopPacket();
60 RTC_CHECK(packet_data);
61 int error = neteq_->InsertPacket(
henrik.lundin246ef3e2017-04-24 09:14:32 -070062 packet_data->header,
henrik.lundine8a77e32016-06-22 06:34:03 -070063 rtc::ArrayView<const uint8_t>(packet_data->payload),
64 static_cast<uint32_t>(packet_data->time_ms * sample_rate_hz_ / 1000));
henrik.lundin02739d92017-05-04 06:09:06 -070065 if (error != NetEq::kOK && callbacks_.error_callback) {
Henrik Lundinc417d9e2017-06-14 12:29:03 +020066 callbacks_.error_callback->OnInsertPacketError(*packet_data);
henrik.lundin02739d92017-05-04 06:09:06 -070067 }
68 if (callbacks_.post_insert_packet) {
69 callbacks_.post_insert_packet->AfterInsertPacket(*packet_data,
70 neteq_.get());
henrik.lundine8a77e32016-06-22 06:34:03 -070071 }
72 }
73
74 // Check if it is time to get output audio.
75 if (input_->NextOutputEventTime() &&
76 time_now_ms >= *input_->NextOutputEventTime()) {
henrik.lundin02739d92017-05-04 06:09:06 -070077 if (callbacks_.get_audio_callback) {
78 callbacks_.get_audio_callback->BeforeGetAudio(neteq_.get());
79 }
henrik.lundine8a77e32016-06-22 06:34:03 -070080 AudioFrame out_frame;
81 bool muted;
82 int error = neteq_->GetAudio(&out_frame, &muted);
83 RTC_CHECK(!muted) << "The code does not handle enable_muted_state";
84 if (error != NetEq::kOK) {
henrik.lundin02739d92017-05-04 06:09:06 -070085 if (callbacks_.error_callback) {
Henrik Lundinc417d9e2017-06-14 12:29:03 +020086 callbacks_.error_callback->OnGetAudioError();
henrik.lundine8a77e32016-06-22 06:34:03 -070087 }
88 } else {
89 sample_rate_hz_ = out_frame.sample_rate_hz_;
90 }
henrik.lundin02739d92017-05-04 06:09:06 -070091 if (callbacks_.get_audio_callback) {
92 callbacks_.get_audio_callback->AfterGetAudio(time_now_ms, out_frame,
93 muted, neteq_.get());
94 }
henrik.lundine8a77e32016-06-22 06:34:03 -070095
96 if (output_) {
97 RTC_CHECK(output_->WriteArray(
yujo36b1a5f2017-06-12 12:45:32 -070098 out_frame.data(),
henrik.lundine8a77e32016-06-22 06:34:03 -070099 out_frame.samples_per_channel_ * out_frame.num_channels_));
100 }
101
102 input_->AdvanceOutputEvent();
103 }
104 }
105 return time_now_ms - start_time_ms;
106}
107
108NetEqNetworkStatistics NetEqTest::SimulationStats() {
109 NetEqNetworkStatistics stats;
110 RTC_CHECK_EQ(neteq_->NetworkStatistics(&stats), 0);
111 return stats;
112}
113
Alex Narest7ff6ca52018-02-07 18:46:33 +0100114NetEqLifetimeStatistics NetEqTest::LifetimeStats() const {
115 return neteq_->GetLifetimeStatistics();
116}
117
Henrik Lundin7687ad52018-07-02 10:14:46 +0200118NetEqTest::DecoderMap NetEqTest::StandardDecoderMap() {
119 DecoderMap codecs = {
120 {0, std::make_pair(NetEqDecoder::kDecoderPCMu, "pcmu")},
121 {8, std::make_pair(NetEqDecoder::kDecoderPCMa, "pcma")},
122#ifdef WEBRTC_CODEC_ILBC
123 {102, std::make_pair(NetEqDecoder::kDecoderILBC, "ilbc")},
124#endif
125 {103, std::make_pair(NetEqDecoder::kDecoderISAC, "isac")},
126#if !defined(WEBRTC_ANDROID)
127 {104, std::make_pair(NetEqDecoder::kDecoderISACswb, "isac-swb")},
128#endif
129#ifdef WEBRTC_CODEC_OPUS
130 {111, std::make_pair(NetEqDecoder::kDecoderOpus, "opus")},
131#endif
132 {93, std::make_pair(NetEqDecoder::kDecoderPCM16B, "pcm16-nb")},
133 {94, std::make_pair(NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb")},
134 {95, std::make_pair(NetEqDecoder::kDecoderPCM16Bswb32kHz, "pcm16-swb32")},
135 {96, std::make_pair(NetEqDecoder::kDecoderPCM16Bswb48kHz, "pcm16-swb48")},
136 {9, std::make_pair(NetEqDecoder::kDecoderG722, "g722")},
137 {106, std::make_pair(NetEqDecoder::kDecoderAVT, "avt")},
138 {114, std::make_pair(NetEqDecoder::kDecoderAVT16kHz, "avt-16")},
139 {115, std::make_pair(NetEqDecoder::kDecoderAVT32kHz, "avt-32")},
140 {116, std::make_pair(NetEqDecoder::kDecoderAVT48kHz, "avt-48")},
141 {117, std::make_pair(NetEqDecoder::kDecoderRED, "red")},
142 {13, std::make_pair(NetEqDecoder::kDecoderCNGnb, "cng-nb")},
143 {98, std::make_pair(NetEqDecoder::kDecoderCNGwb, "cng-wb")},
144 {99, std::make_pair(NetEqDecoder::kDecoderCNGswb32kHz, "cng-swb32")},
145 {100, std::make_pair(NetEqDecoder::kDecoderCNGswb48kHz, "cng-swb48")}
146 };
147 return codecs;
148}
149
henrik.lundine8a77e32016-06-22 06:34:03 -0700150void NetEqTest::RegisterDecoders(const DecoderMap& codecs) {
151 for (const auto& c : codecs) {
152 RTC_CHECK_EQ(
153 neteq_->RegisterPayloadType(c.second.first, c.second.second, c.first),
154 NetEq::kOK)
155 << "Cannot register " << c.second.second << " to payload type "
156 << c.first;
157 }
158}
159
160void NetEqTest::RegisterExternalDecoders(const ExtDecoderMap& codecs) {
161 for (const auto& c : codecs) {
162 RTC_CHECK_EQ(
163 neteq_->RegisterExternalDecoder(c.second.decoder, c.second.codec,
164 c.second.codec_name, c.first),
165 NetEq::kOK)
166 << "Cannot register " << c.second.codec_name << " to payload type "
167 << c.first;
168 }
169}
170
171} // namespace test
172} // namespace webrtc