OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 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 "webrtc/test/fuzzers/audio_processing_fuzzer.h" | |
12 | |
13 #include <algorithm> | |
14 #include <array> | |
15 #include <cmath> | |
16 | |
17 #include "webrtc/base/checks.h" | |
18 #include "webrtc/modules/audio_processing/include/audio_processing.h" | |
19 #include "webrtc/modules/include/module_common_types.h" | |
20 | |
21 namespace webrtc { | |
22 namespace { | |
23 size_t ByteToNativeRate(uint8_t data) { | |
24 using Rate = AudioProcessing::NativeRate; | |
25 switch (data % 4) { | |
26 case 0: | |
27 // Breaks AEC3. | |
28 // return static_cast<size_t>(Rate::kSampleRate8kHz); | |
29 case 1: | |
30 return static_cast<size_t>(Rate::kSampleRate16kHz); | |
31 case 2: | |
32 return static_cast<size_t>(Rate::kSampleRate32kHz); | |
33 default: | |
34 return static_cast<size_t>(Rate::kSampleRate48kHz); | |
35 } | |
36 } | |
37 } // namespace | |
38 | |
39 rtc::Optional<bool> ParseBool(const uint8_t** data, size_t* remaining_size) { | |
40 if (1 > *remaining_size) { | |
41 return rtc::Optional<bool>(); | |
42 } | |
43 auto res = rtc::Optional<bool>((**data) % 2); | |
44 *data += 1; | |
45 *remaining_size -= 1; | |
46 return res; | |
47 } | |
48 | |
49 rtc::Optional<uint8_t> ParseByte(const uint8_t** data, size_t* remaining_size) { | |
50 if (1 > *remaining_size) { | |
51 return rtc::Optional<uint8_t>(); | |
52 } | |
53 auto res = rtc::Optional<uint8_t>((**data)); | |
54 *data += 1; | |
55 *remaining_size -= 1; | |
56 return res; | |
57 } | |
58 | |
59 template <class T> | |
60 bool ParseSequence(size_t size, | |
hlundin-webrtc
2017/06/16 14:48:27
ParseSequence and FuzzAudioProcessingFixed are onl
aleloi
2017/06/19 11:31:42
Done.
| |
61 const uint8_t** data, | |
62 size_t* remaining_size, | |
63 T* result_data) { | |
64 const size_t data_size = sizeof(float) * size; | |
hlundin-webrtc
2017/06/16 14:48:27
Shouldn't it be sizeof(T)?
hlundin-webrtc
2017/06/16 14:48:27
data_size_bytes
aleloi
2017/06/19 11:31:42
Thanks, missed that!
aleloi
2017/06/19 11:31:42
Done.
| |
65 if (data_size > *remaining_size) { | |
66 return false; | |
67 } | |
68 | |
69 std::copy(*data, *data + data_size, reinterpret_cast<uint8_t*>(result_data)); | |
70 | |
71 *data += data_size; | |
72 *remaining_size -= data_size; | |
73 return true; | |
74 } | |
75 | |
76 void FuzzAudioProcessingFixed(const uint8_t* data, | |
hlundin-webrtc
2017/06/16 14:48:26
Why is it called Fixed?
aleloi
2017/06/19 11:31:43
In another version, I had FuzzFixed and FuzzFloati
| |
77 size_t size, | |
78 bool is_float, | |
79 AudioProcessing* apm) { | |
80 AudioFrame fixed_frame; | |
81 std::array<float, 480> float_frame; | |
82 float* const first_channel = float_frame.begin(); | |
83 | |
84 while (size > 0) { | |
85 // Decide input/output rate for this iteration. | |
86 const auto input_rate_byte = ParseByte(&data, &size); | |
87 const auto output_rate_byte = ParseByte(&data, &size); | |
88 if (!input_rate_byte || !output_rate_byte) { | |
89 return; | |
90 } | |
91 const auto input_rate = ByteToNativeRate(*input_rate_byte); | |
hlundin-webrtc
2017/06/16 14:48:27
{input, output}_rate_hz
aleloi
2017/06/19 11:31:42
Done.
| |
92 const auto output_rate = ByteToNativeRate(*output_rate_byte); | |
93 | |
94 const size_t samples_per_input_channel = | |
hlundin-webrtc
2017/06/16 14:48:27
This is the number of samples per millisecond. Is
aleloi
2017/06/19 11:31:42
Wow, that actually led to the fix-point interface
| |
95 rtc::CheckedDivExact(input_rate, 1000ul); | |
96 fixed_frame.samples_per_channel_ = samples_per_input_channel; | |
97 fixed_frame.sample_rate_hz_ = input_rate; | |
98 | |
99 // Two channels breaks AEC3. | |
100 fixed_frame.num_channels_ = 1; | |
101 | |
102 // Fill the arrays with audio samples from the data. | |
103 if (is_float) { | |
104 if (!ParseSequence(samples_per_input_channel, &data, &size, | |
105 float_frame.begin())) { | |
hlundin-webrtc
2017/06/16 14:48:27
I would have expected &float_frame[0], but I assum
aleloi
2017/06/19 11:31:42
I started thinking about whether this is safe and
| |
106 break; | |
hlundin-webrtc
2017/06/16 14:48:26
Why not simply return?
aleloi
2017/06/19 11:31:42
Done.
| |
107 } | |
108 } else if (!ParseSequence(samples_per_input_channel, &data, &size, | |
109 fixed_frame.mutable_data())) { | |
110 break; | |
hlundin-webrtc
2017/06/16 14:48:27
return?
aleloi
2017/06/19 11:31:42
Done.
| |
111 } | |
112 | |
113 // Filter obviously wrong values like inf/nan and values that will | |
114 // lead to inf/nan in calculations. 1e6 leads to DCHECKS failing. | |
115 for (auto& x : float_frame) { | |
116 if (!std::isnormal(x) || std::abs(x) > 1e5) { | |
117 x = 0; | |
118 } | |
119 } | |
120 | |
121 // Make the APM call depending on capture/render mode and float / | |
122 // fix interface. | |
123 const auto is_capture = ParseBool(&data, &size); | |
124 if (!is_capture) { | |
125 break; | |
hlundin-webrtc
2017/06/16 14:48:27
return?
aleloi
2017/06/19 11:31:42
Done.
| |
126 } | |
127 if (*is_capture) { | |
128 is_float | |
129 ? (apm->ProcessStream(&first_channel, StreamConfig(input_rate, 1), | |
130 StreamConfig(output_rate, 1), &first_channel)) | |
131 : (apm->ProcessStream(&fixed_frame)); | |
132 | |
133 } else { | |
134 is_float ? (apm->ProcessReverseStream( | |
135 &first_channel, StreamConfig(input_rate, 1), | |
136 StreamConfig(output_rate, 1), &first_channel)) | |
137 : (apm->ProcessReverseStream(&fixed_frame)); | |
138 } | |
139 } | |
140 } | |
141 | |
142 void FuzzAudioProcessing(const uint8_t* data, | |
143 size_t size, | |
144 std::unique_ptr<AudioProcessing> apm) { | |
145 FuzzAudioProcessingFixed(data, size, false, apm.get()); | |
hlundin-webrtc
2017/06/16 14:48:27
Why not let fixed/float also depend on the fuzzer
aleloi
2017/06/19 11:31:42
Done.
| |
146 FuzzAudioProcessingFixed(data, size, true, apm.get()); | |
147 } | |
148 } // namespace webrtc | |
OLD | NEW |