You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.8 KiB
90 lines
2.8 KiB
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include <fuzzer/FuzzedDataProvider.h>
|
|
|
|
#include "../g722_enc_dec.h"
|
|
|
|
uint32_t get_rate_from_fdp(FuzzedDataProvider* fdp) {
|
|
uint32_t rate = fdp->ConsumeIntegralInRange<uint32_t>(
|
|
0, 3); // Currently 3 different bit rates are available in G.722 codec
|
|
switch (rate) {
|
|
case 0:
|
|
return 48000;
|
|
case 1:
|
|
return 56000;
|
|
default:
|
|
return 64000;
|
|
}
|
|
}
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
FuzzedDataProvider fdp(data, size);
|
|
|
|
std::vector<uint8_t> buff;
|
|
for (size_t i = 0; i < size; i++) {
|
|
buff.push_back(data[i]);
|
|
}
|
|
|
|
int num_samples =
|
|
buff.size() / (2 /*bytes_per_sample*/ * 2 /*number of channels*/);
|
|
|
|
// The G.722 codec accept only even number of samples for encoding
|
|
if (num_samples % 2 != 0) {
|
|
num_samples--;
|
|
}
|
|
|
|
// Making channel data from buffer
|
|
std::vector<uint16_t> channel_data;
|
|
|
|
for (int i = 0; i < num_samples; i++) {
|
|
const uint8_t* sample = buff.data() + i * 2;
|
|
int16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
|
|
|
|
sample += 2;
|
|
int16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
|
|
|
|
uint16_t mono_data = (int16_t)(((uint32_t)left + (uint32_t)right) >> 1);
|
|
channel_data.push_back(mono_data);
|
|
}
|
|
|
|
uint32_t rate = get_rate_from_fdp(&fdp);
|
|
|
|
// Encoder Initialization
|
|
g722_encode_state_t* encoder_state = nullptr;
|
|
encoder_state = g722_encode_init(nullptr, rate, G722_PACKED);
|
|
|
|
// Encode
|
|
std::vector<uint8_t> encoded_data;
|
|
// Magic number is used in api, It should basically fit the number generated
|
|
// by this formula : num_channels * sample_rate * data_interval_ms
|
|
// * (bit_rate / 8)) / 1000 as mentioned in hearing_aid.cc And if we fit all
|
|
// the values in the above formula, the max value we can get is 1920. And I
|
|
// used "size" of the input that libfuzzer generates as the initial
|
|
// parameter to resize
|
|
encoded_data.resize(size);
|
|
int encoded_size =
|
|
g722_encode(encoder_state, encoded_data.data(),
|
|
(const int16_t*)channel_data.data(), channel_data.size());
|
|
encoded_data.resize(encoded_size);
|
|
|
|
// Encoder release
|
|
if (encoder_state != nullptr) {
|
|
g722_encode_release(encoder_state);
|
|
encoder_state = nullptr;
|
|
}
|
|
|
|
return 0;
|
|
} |