NetEqTest: Extend the callback structure

This change allows more callbacks to be registered to the test object.
The callbacks are used to give the user of the test object the ability
to instrument the test object. This CL specifically adds
instrumentation points just after a packet is inserted into NetEq, and
just after audio is pulled out of NetEq.

BUG=webrtc:7467

Review-Url: https://codereview.webrtc.org/2851383004
Cr-Commit-Position: refs/heads/master@{#18014}
This commit is contained in:
henrik.lundin 2017-05-04 06:09:06 -07:00 committed by Commit bot
parent f25a22041c
commit 02739d9149
4 changed files with 47 additions and 12 deletions

View File

@ -445,11 +445,11 @@ int RunTest(int argc, char* argv[]) {
ext_codecs[replacement_pt] = ext_dec_info;
}
DefaultNetEqTestErrorCallback error_cb;
NetEqTest::Callbacks callbacks;
NetEq::Config config;
config.sample_rate_hz = sample_rate_hz;
NetEqTest test(config, codecs, ext_codecs, std::move(input),
std::move(output), &error_cb);
std::move(output), callbacks);
int64_t test_duration_ms = test.Run();
NetEqNetworkStatistics stats = test.SimulationStats();

View File

@ -41,11 +41,11 @@ NetEqTest::NetEqTest(const NetEq::Config& config,
const ExtDecoderMap& ext_codecs,
std::unique_ptr<NetEqInput> input,
std::unique_ptr<AudioSink> output,
NetEqTestErrorCallback* error_callback)
Callbacks callbacks)
: neteq_(NetEq::Create(config, CreateBuiltinAudioDecoderFactory())),
input_(std::move(input)),
output_(std::move(output)),
error_callback_(error_callback),
callbacks_(callbacks),
sample_rate_hz_(config.sample_rate_hz) {
RTC_CHECK(!config.enable_muted_state)
<< "The code does not handle enable_muted_state";
@ -69,25 +69,37 @@ int64_t NetEqTest::Run() {
packet_data->header,
rtc::ArrayView<const uint8_t>(packet_data->payload),
static_cast<uint32_t>(packet_data->time_ms * sample_rate_hz_ / 1000));
if (error != NetEq::kOK && error_callback_) {
error_callback_->OnInsertPacketError(neteq_->LastError(), *packet_data);
if (error != NetEq::kOK && callbacks_.error_callback) {
callbacks_.error_callback->OnInsertPacketError(neteq_->LastError(),
*packet_data);
}
if (callbacks_.post_insert_packet) {
callbacks_.post_insert_packet->AfterInsertPacket(*packet_data,
neteq_.get());
}
}
// Check if it is time to get output audio.
if (input_->NextOutputEventTime() &&
time_now_ms >= *input_->NextOutputEventTime()) {
if (callbacks_.get_audio_callback) {
callbacks_.get_audio_callback->BeforeGetAudio(neteq_.get());
}
AudioFrame out_frame;
bool muted;
int error = neteq_->GetAudio(&out_frame, &muted);
RTC_CHECK(!muted) << "The code does not handle enable_muted_state";
if (error != NetEq::kOK) {
if (error_callback_) {
error_callback_->OnGetAudioError(neteq_->LastError());
if (callbacks_.error_callback) {
callbacks_.error_callback->OnGetAudioError(neteq_->LastError());
}
} else {
sample_rate_hz_ = out_frame.sample_rate_hz_;
}
if (callbacks_.get_audio_callback) {
callbacks_.get_audio_callback->AfterGetAudio(time_now_ms, out_frame,
muted, neteq_.get());
}
if (output_) {
RTC_CHECK(output_->WriteArray(

View File

@ -37,6 +37,23 @@ class DefaultNetEqTestErrorCallback : public NetEqTestErrorCallback {
void OnGetAudioError(int error_code) override;
};
class NetEqPostInsertPacket {
public:
virtual ~NetEqPostInsertPacket() = default;
virtual void AfterInsertPacket(const NetEqInput::PacketData& packet,
NetEq* neteq) = 0;
};
class NetEqGetAudioCallback {
public:
virtual ~NetEqGetAudioCallback() = default;
virtual void BeforeGetAudio(NetEq* neteq) = 0;
virtual void AfterGetAudio(int64_t time_now_ms,
const AudioFrame& audio_frame,
bool muted,
NetEq* neteq) = 0;
};
// Class that provides an input--output test for NetEq. The input (both packets
// and output events) is provided by a NetEqInput object, while the output is
// directed to an AudioSink object.
@ -52,6 +69,12 @@ class NetEqTest {
using ExtDecoderMap = std::map<int, ExternalDecoderInfo>;
struct Callbacks {
NetEqTestErrorCallback* error_callback = nullptr;
NetEqPostInsertPacket* post_insert_packet = nullptr;
NetEqGetAudioCallback* get_audio_callback = nullptr;
};
// Sets up the test with given configuration, codec mappings, input, ouput,
// and callback objects for error reporting.
NetEqTest(const NetEq::Config& config,
@ -59,7 +82,7 @@ class NetEqTest {
const ExtDecoderMap& ext_codecs,
std::unique_ptr<NetEqInput> input,
std::unique_ptr<AudioSink> output,
NetEqTestErrorCallback* error_callback);
Callbacks callbacks);
~NetEqTest() = default;
@ -76,7 +99,7 @@ class NetEqTest {
std::unique_ptr<NetEq> neteq_;
std::unique_ptr<NetEqInput> input_;
std::unique_ptr<AudioSink> output_;
NetEqTestErrorCallback* error_callback_ = nullptr;
Callbacks callbacks_;
int sample_rate_hz_;
};

View File

@ -127,7 +127,7 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) {
std::unique_ptr<FuzzRtpInput> input(
new FuzzRtpInput(rtc::ArrayView<const uint8_t>(data, size)));
std::unique_ptr<AudioChecksum> output(new AudioChecksum);
NetEqTestErrorCallback dummy_callback; // Does nothing with error callbacks.
NetEqTest::Callbacks callbacks;
NetEq::Config config;
NetEqTest::DecoderMap codecs;
codecs[0] = std::make_pair(NetEqDecoder::kDecoderPCMu, "pcmu");
@ -155,7 +155,7 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) {
NetEqTest::ExtDecoderMap ext_codecs;
NetEqTest test(config, codecs, ext_codecs, std::move(input),
std::move(output), &dummy_callback);
std::move(output), callbacks);
test.Run();
}