diff options
Diffstat (limited to 'third_party/libwebrtc/test/fuzzers/agc_fuzzer.cc')
-rw-r--r-- | third_party/libwebrtc/test/fuzzers/agc_fuzzer.cc | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/fuzzers/agc_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/agc_fuzzer.cc new file mode 100644 index 0000000000..597103993e --- /dev/null +++ b/third_party/libwebrtc/test/fuzzers/agc_fuzzer.cc @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <memory> + +#include "modules/audio_processing/audio_buffer.h" +#include "modules/audio_processing/gain_control_impl.h" +#include "modules/audio_processing/include/audio_processing.h" +#include "rtc_base/numerics/safe_minmax.h" +#include "rtc_base/thread_annotations.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +namespace { + +void FillAudioBuffer(size_t sample_rate_hz, + test::FuzzDataHelper* fuzz_data, + AudioBuffer* buffer) { + float* const* channels = buffer->channels_f(); + for (size_t i = 0; i < buffer->num_channels(); ++i) { + for (size_t j = 0; j < buffer->num_frames(); ++j) { + channels[i][j] = + static_cast<float>(fuzz_data->ReadOrDefaultValue<int16_t>(0)); + } + } + + if (sample_rate_hz != 16000) { + buffer->SplitIntoFrequencyBands(); + } +} + +// This function calls the GainControl functions that are overriden as private +// in GainControlInterface. +void FuzzGainControllerConfig(test::FuzzDataHelper* fuzz_data, + GainControl* gc) { + GainControl::Mode modes[] = {GainControl::Mode::kAdaptiveAnalog, + GainControl::Mode::kAdaptiveDigital, + GainControl::Mode::kFixedDigital}; + GainControl::Mode mode = fuzz_data->SelectOneOf(modes); + const bool enable_limiter = fuzz_data->ReadOrDefaultValue(true); + // The values are capped to comply with the API of webrtc::GainControl. + const int analog_level_min = + rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<uint16_t>(0), 0, 65534); + const int analog_level_max = + rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<uint16_t>(65535), + analog_level_min + 1, 65535); + const int stream_analog_level = + rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<uint16_t>(30000), + analog_level_min, analog_level_max); + const int gain = + rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<int8_t>(30), -1, 100); + const int target_level_dbfs = + rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<int8_t>(15), -1, 35); + + gc->set_mode(mode); + gc->enable_limiter(enable_limiter); + if (mode == GainControl::Mode::kAdaptiveAnalog) { + gc->set_analog_level_limits(analog_level_min, analog_level_max); + gc->set_stream_analog_level(stream_analog_level); + } + gc->set_compression_gain_db(gain); + gc->set_target_level_dbfs(target_level_dbfs); + + static_cast<void>(gc->mode()); + static_cast<void>(gc->analog_level_minimum()); + static_cast<void>(gc->analog_level_maximum()); + static_cast<void>(gc->stream_analog_level()); + static_cast<void>(gc->compression_gain_db()); + static_cast<void>(gc->stream_is_saturated()); + static_cast<void>(gc->target_level_dbfs()); + static_cast<void>(gc->is_limiter_enabled()); +} + +void FuzzGainController(test::FuzzDataHelper* fuzz_data, GainControlImpl* gci) { + using Rate = ::webrtc::AudioProcessing::NativeRate; + const Rate rate_kinds[] = {Rate::kSampleRate16kHz, Rate::kSampleRate32kHz, + Rate::kSampleRate48kHz}; + + const auto sample_rate_hz = + static_cast<size_t>(fuzz_data->SelectOneOf(rate_kinds)); + const size_t samples_per_frame = sample_rate_hz / 100; + const size_t num_channels = fuzz_data->ReadOrDefaultValue(true) ? 2 : 1; + + gci->Initialize(num_channels, sample_rate_hz); + FuzzGainControllerConfig(fuzz_data, gci); + + // The audio buffer is used for both capture and render. + AudioBuffer audio(sample_rate_hz, num_channels, sample_rate_hz, + num_channels, sample_rate_hz, num_channels); + + std::vector<int16_t> packed_render_audio(samples_per_frame); + + while (fuzz_data->CanReadBytes(1)) { + FillAudioBuffer(sample_rate_hz, fuzz_data, &audio); + + const bool stream_has_echo = fuzz_data->ReadOrDefaultValue(true); + gci->AnalyzeCaptureAudio(audio); + gci->ProcessCaptureAudio(&audio, stream_has_echo); + + FillAudioBuffer(sample_rate_hz, fuzz_data, &audio); + + gci->PackRenderAudioBuffer(audio, &packed_render_audio); + gci->ProcessRenderAudio(packed_render_audio); + } +} + +} // namespace + +void FuzzOneInput(const uint8_t* data, size_t size) { + if (size > 200000) { + return; + } + test::FuzzDataHelper fuzz_data(rtc::ArrayView<const uint8_t>(data, size)); + auto gci = std::make_unique<GainControlImpl>(); + FuzzGainController(&fuzz_data, gci.get()); +} +} // namespace webrtc |