mirror of https://github.com/mstorsjo/fdk-aac.git
Merge remote-tracking branch 'aosp/master'
This commit is contained in:
commit
a52114dd69
10
Android.bp
10
Android.bp
|
@ -32,8 +32,7 @@ cc_library_static {
|
|||
"signed-integer-overflow",
|
||||
"bounds",
|
||||
],
|
||||
// Enable CFI if this becomes a shared library.
|
||||
// cfi: true,
|
||||
cfi: true,
|
||||
},
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
|
@ -58,6 +57,13 @@ cc_library_static {
|
|||
darwin: {
|
||||
enabled: false,
|
||||
},
|
||||
android: {
|
||||
sanitize: {
|
||||
diag: {
|
||||
cfi: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
apex_available: [
|
||||
|
|
|
@ -18,17 +18,12 @@
|
|||
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
||||
*/
|
||||
|
||||
cc_fuzz {
|
||||
name: "aac_dec_fuzzer",
|
||||
host_supported:true,
|
||||
cc_defaults {
|
||||
name: "aac_fuzz_defaults",
|
||||
host_supported: true,
|
||||
|
||||
static_libs: [
|
||||
"libFraunhoferAAC",
|
||||
"liblog",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"aac_dec_fuzzer.cpp",
|
||||
],
|
||||
|
||||
target: {
|
||||
|
@ -44,3 +39,31 @@ cc_fuzz {
|
|||
componentid: 155276,
|
||||
},
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "aac_dec_fuzzer",
|
||||
|
||||
srcs: [
|
||||
"aac_dec_fuzzer.cpp",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"liblog",
|
||||
],
|
||||
|
||||
defaults: [
|
||||
"aac_fuzz_defaults"
|
||||
],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "aac_enc_fuzzer",
|
||||
|
||||
srcs: [
|
||||
"aac_enc_fuzzer.cpp",
|
||||
],
|
||||
|
||||
defaults: [
|
||||
"aac_fuzz_defaults"
|
||||
],
|
||||
}
|
||||
|
|
|
@ -53,7 +53,85 @@ To run on host
|
|||
$ $ANDROID_HOST_OUT/fuzz/x86_64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
|
||||
```
|
||||
|
||||
# Fuzzer for libFraunhoferAAC encoder
|
||||
|
||||
## Plugin Design Considerations
|
||||
The fuzzer plugin for aac encoder is designed based on the understanding of the
|
||||
codec and tries to achieve the following:
|
||||
|
||||
##### Maximize code coverage
|
||||
|
||||
The configuration parameters are not hardcoded, but instead selected based on
|
||||
incoming data. This ensures more code paths are reached by the fuzzer.
|
||||
|
||||
Following arguments are passed to aacEncoder_SetParam to set the respective AACENC_PARAM parameter:
|
||||
|
||||
| Variable name| AACENC_PARAM param| Valid Values| Configured Value|
|
||||
|------------- |-------------| ----- |----- |
|
||||
| `sbrMode` |`AACENC_SBR_MODE` | `AAC_SBR_OFF ` `AAC_SBR_SINGLE_RATE ` `AAC_SBR_DUAL_RATE ` `AAC_SBR_AUTO ` | Calculated using first byte of data |
|
||||
| `aacAOT` | `AACENC_AOT` |`AOT_AAC_LC ` `AOT_ER_AAC_ELD ` `AOT_SBR ` `AOT_PS ` `AOT_ER_AAC_LD ` | Calculated using second byte of data |
|
||||
| `sampleRate` |`AACENC_SAMPLERATE` | `8000 ` `11025 ` `12000 ` `16000 ` `22050 ` `24000 ` `32000 ` `44100 ` `48000 `| Calculated using third byte of data |
|
||||
| `bitRate` |`AACENC_BITRATE` | In range `8000 ` to `960000 ` | Calculated using fourth, fifth and sixth byte of data |
|
||||
| `channelMode` |`AACENC_CHANNELMODE` | `MODE_1 ` `MODE_2 ` `MODE_1_2 ` `MODE_1_2_1 ` `MODE_1_2_2 ` `MODE_1_2_2_1 ` `MODE_1_2_2_2_1 ` `MODE_7_1_BACK ` | Calculated using seventh byte of data |
|
||||
| `identifier` |`AACENC_TRANSMUX` | `TT_MP4_RAW ` `TT_MP4_ADIF ` `TT_MP4_ADTS ` `TT_MP4_LATM_MCP1 ` `TT_MP4_LATM_MCP0 ` `TT_MP4_LOAS ` `TT_DRM ` | Calculated using eight byte of data |
|
||||
| `sbrRatio` | `AACENC_SBR_RATIO` |`0 ` `1 ` `2 ` | Calculated using ninth byte of data |
|
||||
|
||||
Following values are configured to set up the meta data represented by the class variable `mMetaData ` :
|
||||
| Variable name| Possible Values| Configured Value|
|
||||
|------------- | ----- |----- |
|
||||
| `drc_profile` | `AACENC_METADATA_DRC_NONE ` `AACENC_METADATA_DRC_FILMSTANDARD ` `AACENC_METADATA_DRC_FILMLIGHT ` `AACENC_METADATA_DRC_MUSICSTANDARD ` `AACENC_METADATA_DRC_MUSICLIGHT ` `AACENC_METADATA_DRC_SPEECH ` `AACENC_METADATA_DRC_NOT_PRESENT ` | Calculated using tenth byte of data |
|
||||
| `comp_profile` | `AACENC_METADATA_DRC_NONE ` `AACENC_METADATA_DRC_FILMSTANDARD ` `AACENC_METADATA_DRC_FILMLIGHT ` `AACENC_METADATA_DRC_MUSICSTANDARD ` `AACENC_METADATA_DRC_MUSICLIGHT ` `AACENC_METADATA_DRC_SPEECH ` `AACENC_METADATA_DRC_NOT_PRESENT ` | Calculated using eleventh byte of data |
|
||||
| `drc_TargetRefLevel` | In range `0 ` to `255 ` | Calculated using twelfth byte of data |
|
||||
| `comp_TargetRefLevel` | In range `0 ` to `255 ` | Calculated using thirteenth byte of data |
|
||||
| `prog_ref_level_present` | `0 ` `1 ` | Calculated using fourteenth byte of data |
|
||||
| `prog_ref_level` | In range `0 ` to `255 ` | Calculated using fifteenth byte of data |
|
||||
| `PCE_mixdown_idx_present` | `0 ` `1 ` | Calculated using sixteenth byte of data |
|
||||
| `ETSI_DmxLvl_present` | `0 ` `1 ` | Calculated using seventeenth byte of data |
|
||||
| `centerMixLevel` | In range `0 ` to `7 ` | Calculated using eighteenth byte of data |
|
||||
| `surroundMixLevel` | In range `0 ` to `7 ` | Calculated using nineteenth byte of data |
|
||||
| `dolbySurroundMode` | In range `0 ` to `2 ` | Calculated using twentieth byte of data |
|
||||
| `drcPresentationMode` | In range `0 ` to `2 ` | Calculated using twenty-first byte of data |
|
||||
| `extAncDataEnable` | `0 ` `1 ` | Calculated using twenty-second byte of data |
|
||||
| `extDownmixLevelEnable` | `0 ` `1 ` | Calculated using twenty-third byte of data |
|
||||
| `extDownmixLevel_A` | In range `0 ` to `7 ` | Calculated using twenty-fourth byte of data |
|
||||
| `extDownmixLevel_B` | In range `0 ` to `7 ` | Calculated using twenty-fifth byte of data |
|
||||
| `dmxGainEnable` | `0 ` `1 ` | Calculated using twenty-sixth byte of data |
|
||||
| `dmxGain5` | In range `0 ` to `255 ` | Calculated using twenty-seventh byte of data |
|
||||
| `dmxGain2` | In range `0 ` to `255 ` | Calculated using twenty-eighth byte of data |
|
||||
| `lfeDmxEnable` | `0 ` `1 ` | Calculated using twenty-ninth byte of data |
|
||||
| `lfeDmxLevel` | In range `0 ` to `15 ` | Calculated using thirtieth byte of data |
|
||||
|
||||
Indexes `mInBufferIdx_1`, `mInBufferIdx_2` and `mInBufferIdx_3`(in range `0 ` to `2`) are calculated using the thirty-first, thirty-second and thirty-third byte respectively.
|
||||
|
||||
##### Maximize utilization of input data
|
||||
The plugin feeds the entire input data to the codec and continues with the encoding even on a failure. This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc) and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities.
|
||||
|
||||
## Build
|
||||
|
||||
This describes steps to build aac_enc_fuzzer binary.
|
||||
|
||||
## Android
|
||||
|
||||
### Steps to build
|
||||
Build the fuzzer
|
||||
```
|
||||
$ mm -j$(nproc) aac_enc_fuzzer
|
||||
```
|
||||
|
||||
### Steps to run
|
||||
Create a directory CORPUS_DIR and copy some raw files to that folder.
|
||||
Push this directory to device.
|
||||
|
||||
To run on device
|
||||
```
|
||||
$ adb sync data
|
||||
$ adb shell /data/fuzz/arm64/aac_enc_fuzzer/aac_enc_fuzzer CORPUS_DIR
|
||||
```
|
||||
To run on host
|
||||
```
|
||||
$ $ANDROID_HOST_OUT/fuzz/x86_64/aac_enc_fuzzer/aac_enc_fuzzer CORPUS_DIR
|
||||
```
|
||||
|
||||
## References:
|
||||
* http://llvm.org/docs/LibFuzzer.html
|
||||
* https://github.com/google/oss-fuzz
|
||||
|
||||
|
|
|
@ -0,0 +1,374 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "aacenc_lib.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// IN_AUDIO_DATA, IN_ANCILLRY_DATA and IN_METADATA_SETUP
|
||||
constexpr size_t kMaxBuffers = 3;
|
||||
|
||||
constexpr size_t kMaxOutputBufferSize = 8192;
|
||||
|
||||
constexpr uint32_t kMinBitRate = 8000;
|
||||
constexpr uint32_t kMaxBitRate = 960000;
|
||||
|
||||
constexpr uint32_t kSampleRates[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000};
|
||||
constexpr size_t kSampleRatesSize = size(kSampleRates);
|
||||
|
||||
constexpr CHANNEL_MODE kChannelModes[] = {MODE_1, MODE_2, MODE_1_2, MODE_1_2_1,
|
||||
MODE_1_2_2, MODE_1_2_2_1, MODE_1_2_2_2_1, MODE_7_1_BACK};
|
||||
constexpr size_t kChannelModesSize = size(kChannelModes);
|
||||
|
||||
constexpr TRANSPORT_TYPE kIdentifiers[] = {
|
||||
TT_MP4_RAW, TT_MP4_ADIF, TT_MP4_ADTS, TT_MP4_LATM_MCP1, TT_MP4_LATM_MCP0, TT_MP4_LOAS, TT_DRM};
|
||||
constexpr size_t kIdentifiersSize = size(kIdentifiers);
|
||||
|
||||
constexpr AUDIO_OBJECT_TYPE kAudioObjectTypes[] = {AOT_AAC_LC, AOT_ER_AAC_ELD, AOT_SBR, AOT_PS,
|
||||
AOT_ER_AAC_LD};
|
||||
constexpr size_t kAudioObjectTypesSize = size(kAudioObjectTypes);
|
||||
|
||||
constexpr int32_t kSbrRatios[] = {0, 1, 2};
|
||||
constexpr size_t kSbrRatiosSize = size(kSbrRatios);
|
||||
|
||||
constexpr AACENC_METADATA_DRC_PROFILE kMetaDataDrcProfiles[] = {
|
||||
AACENC_METADATA_DRC_NONE, AACENC_METADATA_DRC_FILMSTANDARD,
|
||||
AACENC_METADATA_DRC_FILMLIGHT, AACENC_METADATA_DRC_MUSICSTANDARD,
|
||||
AACENC_METADATA_DRC_MUSICLIGHT, AACENC_METADATA_DRC_SPEECH,
|
||||
AACENC_METADATA_DRC_NOT_PRESENT};
|
||||
constexpr size_t kMetaDataDrcProfilesSize = size(kMetaDataDrcProfiles);
|
||||
|
||||
enum {
|
||||
IDX_SBR_MODE = 0,
|
||||
IDX_AAC_AOT,
|
||||
IDX_SAMPLE_RATE,
|
||||
IDX_BIT_RATE_1,
|
||||
IDX_BIT_RATE_2,
|
||||
IDX_BIT_RATE_3,
|
||||
IDX_CHANNEL,
|
||||
IDX_IDENTIFIER,
|
||||
IDX_SBR_RATIO,
|
||||
|
||||
IDX_METADATA_DRC_PROFILE,
|
||||
IDX_METADATA_COMP_PROFILE,
|
||||
IDX_METADATA_DRC_TARGET_REF_LEVEL,
|
||||
IDX_METADATA_COMP_TARGET_REF_LEVEL,
|
||||
IDX_METADATA_PROG_LEVEL_PRESENT,
|
||||
IDX_METADATA_PROG_LEVEL,
|
||||
IDX_METADATA_PCE_MIXDOWN_IDX_PRESENT,
|
||||
IDX_METADATA_ETSI_DMXLVL_PRESENT,
|
||||
IDX_METADATA_CENTER_MIX_LEVEL,
|
||||
IDX_METADATA_SURROUND_MIX_LEVEL,
|
||||
IDX_METADATA_DOLBY_SURROUND_MODE,
|
||||
IDX_METADATA_DRC_PRESENTATION_MODE,
|
||||
IDX_METADATA_EXT_ANC_DATA_ENABLE,
|
||||
IDX_METADATA_EXT_DOWNMIX_LEVEL_ENABLE,
|
||||
IDX_METADATA_EXT_DOWNMIX_LEVEL_A,
|
||||
IDX_METADATA_EXT_DOWNMIX_LEVEL_B,
|
||||
IDX_METADATA_DMX_GAIN_ENABLE,
|
||||
IDX_METADATA_DMX_GAIN_5,
|
||||
IDX_METADATA_DMX_GAIN_2,
|
||||
IDX_METADATA_LFE_DMX_ENABLE,
|
||||
IDX_METADATA_LFE_DMX_LEVEL,
|
||||
|
||||
IDX_IN_BUFFER_INDEX_1,
|
||||
IDX_IN_BUFFER_INDEX_2,
|
||||
IDX_IN_BUFFER_INDEX_3,
|
||||
|
||||
IDX_LAST
|
||||
};
|
||||
|
||||
enum aac_sbr_mode_t : uint32_t {
|
||||
AAC_SBR_OFF,
|
||||
AAC_SBR_SINGLE_RATE,
|
||||
AAC_SBR_DUAL_RATE,
|
||||
AAC_SBR_AUTO
|
||||
};
|
||||
|
||||
template <typename type1, typename type2, typename type3>
|
||||
auto generateNumberInRangeFromData(type1 data, type2 min, type3 max) -> decltype(max) {
|
||||
return (data % (1 + max - min)) + min;
|
||||
}
|
||||
|
||||
class Codec {
|
||||
public:
|
||||
~Codec() { deInitEncoder(); }
|
||||
bool initEncoder(uint8_t **dataPtr, size_t *sizePtr);
|
||||
void encodeFrames(const uint8_t *data, size_t size);
|
||||
void deInitEncoder();
|
||||
|
||||
private:
|
||||
void setupMetaData(uint8_t *data);
|
||||
|
||||
HANDLE_AACENCODER mEncoder = nullptr;
|
||||
AACENC_MetaData mMetaData = {};
|
||||
uint32_t mInBufferIdx_1 = 0;
|
||||
uint32_t mInBufferIdx_2 = 0;
|
||||
uint32_t mInBufferIdx_3 = 0;
|
||||
};
|
||||
|
||||
void Codec::setupMetaData(uint8_t *data) {
|
||||
uint32_t drcProfileIndex = generateNumberInRangeFromData(data[IDX_METADATA_DRC_PROFILE], 0,
|
||||
kMetaDataDrcProfilesSize - 1);
|
||||
AACENC_METADATA_DRC_PROFILE drcProfile = kMetaDataDrcProfiles[drcProfileIndex];
|
||||
mMetaData.drc_profile = drcProfile;
|
||||
|
||||
uint32_t compProfileIndex = generateNumberInRangeFromData(data[IDX_METADATA_COMP_PROFILE], 0,
|
||||
kMetaDataDrcProfilesSize - 1);
|
||||
AACENC_METADATA_DRC_PROFILE compProfile = kMetaDataDrcProfiles[compProfileIndex];
|
||||
mMetaData.comp_profile = compProfile;
|
||||
|
||||
INT drcTargetRefLevel =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_DRC_TARGET_REF_LEVEL], 0, UINT8_MAX);
|
||||
mMetaData.drc_TargetRefLevel = drcTargetRefLevel;
|
||||
|
||||
INT compTargetRefLevel =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_COMP_TARGET_REF_LEVEL], 0, UINT8_MAX);
|
||||
mMetaData.comp_TargetRefLevel = compTargetRefLevel;
|
||||
|
||||
INT isProgRefLevelPresent =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_PROG_LEVEL_PRESENT], 0, 1);
|
||||
mMetaData.prog_ref_level_present = isProgRefLevelPresent;
|
||||
|
||||
INT progRefLevel = generateNumberInRangeFromData(data[IDX_METADATA_PROG_LEVEL], 0, UINT8_MAX);
|
||||
mMetaData.prog_ref_level = progRefLevel;
|
||||
|
||||
UCHAR isPCEMixdownIdxPresent =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_PCE_MIXDOWN_IDX_PRESENT], 0, 1);
|
||||
mMetaData.PCE_mixdown_idx_present = isPCEMixdownIdxPresent;
|
||||
|
||||
UCHAR isETSIDmxLvlPresent =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_ETSI_DMXLVL_PRESENT], 0, 1);
|
||||
mMetaData.ETSI_DmxLvl_present = isETSIDmxLvlPresent;
|
||||
|
||||
SCHAR centerMixLevel = generateNumberInRangeFromData(data[IDX_METADATA_CENTER_MIX_LEVEL], 0, 7);
|
||||
mMetaData.centerMixLevel = centerMixLevel;
|
||||
|
||||
SCHAR surroundMixLevel =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_SURROUND_MIX_LEVEL], 0, 7);
|
||||
mMetaData.surroundMixLevel = surroundMixLevel;
|
||||
|
||||
UCHAR dolbySurroundMode =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_DOLBY_SURROUND_MODE], 0, 2);
|
||||
mMetaData.dolbySurroundMode = dolbySurroundMode;
|
||||
|
||||
UCHAR drcPresentationMode =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_DRC_PRESENTATION_MODE], 0, 2);
|
||||
mMetaData.drcPresentationMode = drcPresentationMode;
|
||||
|
||||
UCHAR extAncDataEnable =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_EXT_ANC_DATA_ENABLE], 0, 1);
|
||||
mMetaData.ExtMetaData.extAncDataEnable = extAncDataEnable;
|
||||
|
||||
UCHAR extDownmixLevelEnable =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_ENABLE], 0, 1);
|
||||
mMetaData.ExtMetaData.extDownmixLevelEnable = extDownmixLevelEnable;
|
||||
|
||||
UCHAR extDownmixLevel_A =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_A], 0, 7);
|
||||
mMetaData.ExtMetaData.extDownmixLevel_A = extDownmixLevel_A;
|
||||
|
||||
UCHAR extDownmixLevel_B =
|
||||
generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_B], 0, 7);
|
||||
mMetaData.ExtMetaData.extDownmixLevel_B = extDownmixLevel_B;
|
||||
|
||||
UCHAR dmxGainEnable = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_ENABLE], 0, 1);
|
||||
mMetaData.ExtMetaData.dmxGainEnable = dmxGainEnable;
|
||||
|
||||
INT dmxGain5 = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_5], 0, UINT8_MAX);
|
||||
mMetaData.ExtMetaData.dmxGain5 = dmxGain5;
|
||||
|
||||
INT dmxGain2 = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_2], 0, UINT8_MAX);
|
||||
mMetaData.ExtMetaData.dmxGain2 = dmxGain2;
|
||||
|
||||
UCHAR lfeDmxEnable = generateNumberInRangeFromData(data[IDX_METADATA_LFE_DMX_ENABLE], 0, 1);
|
||||
mMetaData.ExtMetaData.lfeDmxEnable = lfeDmxEnable;
|
||||
|
||||
UCHAR lfeDmxLevel = generateNumberInRangeFromData(data[IDX_METADATA_LFE_DMX_LEVEL], 0, 15);
|
||||
mMetaData.ExtMetaData.lfeDmxLevel = lfeDmxLevel;
|
||||
}
|
||||
|
||||
bool Codec::initEncoder(uint8_t **dataPtr, size_t *sizePtr) {
|
||||
uint8_t *data = *dataPtr;
|
||||
|
||||
if (AACENC_OK != aacEncOpen(&mEncoder, 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t sbrMode = generateNumberInRangeFromData(data[IDX_SBR_MODE], (uint32_t)AAC_SBR_OFF,
|
||||
(uint32_t)AAC_SBR_AUTO);
|
||||
aacEncoder_SetParam(mEncoder, AACENC_SBR_MODE, sbrMode);
|
||||
|
||||
uint32_t sbrRatioIndex =
|
||||
generateNumberInRangeFromData(data[IDX_SBR_RATIO], 0, kSbrRatiosSize - 1);
|
||||
int32_t sbrRatio = kSbrRatios[sbrRatioIndex];
|
||||
aacEncoder_SetParam(mEncoder, AACENC_SBR_RATIO, sbrRatio);
|
||||
|
||||
uint32_t aacAOTIndex =
|
||||
generateNumberInRangeFromData(data[IDX_AAC_AOT], 0, kAudioObjectTypesSize - 1);
|
||||
uint32_t aacAOT = kAudioObjectTypes[aacAOTIndex];
|
||||
aacEncoder_SetParam(mEncoder, AACENC_AOT, aacAOT);
|
||||
|
||||
uint32_t sampleRateIndex =
|
||||
generateNumberInRangeFromData(data[IDX_SAMPLE_RATE], 0, kSampleRatesSize - 1);
|
||||
uint32_t sampleRate = kSampleRates[sampleRateIndex];
|
||||
aacEncoder_SetParam(mEncoder, AACENC_SAMPLERATE, sampleRate);
|
||||
|
||||
uint32_t tempValue =
|
||||
(data[IDX_BIT_RATE_1] << 16) | (data[IDX_BIT_RATE_2] << 8) | data[IDX_BIT_RATE_3];
|
||||
uint32_t bitRate = generateNumberInRangeFromData(tempValue, kMinBitRate, kMaxBitRate);
|
||||
aacEncoder_SetParam(mEncoder, AACENC_BITRATE, bitRate);
|
||||
|
||||
uint32_t channelModeIndex =
|
||||
generateNumberInRangeFromData(data[IDX_CHANNEL], 0, kChannelModesSize - 1);
|
||||
CHANNEL_MODE channelMode = kChannelModes[channelModeIndex];
|
||||
aacEncoder_SetParam(mEncoder, AACENC_CHANNELMODE, channelMode);
|
||||
|
||||
uint32_t identifierIndex =
|
||||
generateNumberInRangeFromData(data[IDX_IDENTIFIER], 0, kIdentifiersSize - 1);
|
||||
uint32_t identifier = kIdentifiers[identifierIndex];
|
||||
aacEncoder_SetParam(mEncoder, AACENC_TRANSMUX, identifier);
|
||||
|
||||
mInBufferIdx_1 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_1], 0, kMaxBuffers - 1);
|
||||
mInBufferIdx_2 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_2], 0, kMaxBuffers - 1);
|
||||
mInBufferIdx_3 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_3], 0, kMaxBuffers - 1);
|
||||
|
||||
setupMetaData(data);
|
||||
|
||||
// Not re-using the data which was used for configuration for encoding
|
||||
*dataPtr += IDX_LAST;
|
||||
*sizePtr -= IDX_LAST;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void deleteBuffers(uint8_t **buffers, size_t size) {
|
||||
for (size_t n = 0; n < size; ++n) {
|
||||
delete[] buffers[n];
|
||||
}
|
||||
delete[] buffers;
|
||||
}
|
||||
|
||||
void Codec::encodeFrames(const uint8_t *data, size_t size) {
|
||||
uint8_t *audioData = (uint8_t *)data;
|
||||
uint8_t *ancData = (uint8_t *)data;
|
||||
size_t audioSize = size;
|
||||
size_t ancSize = size;
|
||||
|
||||
while ((audioSize > 0) && (ancSize > 0)) {
|
||||
AACENC_InArgs inargs;
|
||||
memset(&inargs, 0, sizeof(inargs));
|
||||
inargs.numInSamples = audioSize / sizeof(int16_t);
|
||||
inargs.numAncBytes = ancSize;
|
||||
|
||||
void *buffers[] = {(void *)audioData, (void *)ancData, &mMetaData};
|
||||
INT bufferIds[] = {IN_AUDIO_DATA, IN_ANCILLRY_DATA, IN_METADATA_SETUP};
|
||||
INT bufferSizes[] = {static_cast<INT>(audioSize), static_cast<INT>(ancSize),
|
||||
static_cast<INT>(sizeof(mMetaData))};
|
||||
INT bufferElSizes[] = {sizeof(int16_t), sizeof(UCHAR), sizeof(AACENC_MetaData)};
|
||||
|
||||
void *inBuffer[kMaxBuffers] = {};
|
||||
INT inBufferIds[kMaxBuffers] = {};
|
||||
INT inBufferSize[kMaxBuffers] = {};
|
||||
INT inBufferElSize[kMaxBuffers] = {};
|
||||
for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
|
||||
uint32_t Idxs[] = {mInBufferIdx_1, mInBufferIdx_2, mInBufferIdx_3};
|
||||
inBuffer[buffer] = buffers[Idxs[buffer]];
|
||||
inBufferIds[buffer] = bufferIds[Idxs[buffer]];
|
||||
inBufferSize[buffer] = bufferSizes[Idxs[buffer]];
|
||||
inBufferElSize[buffer] = bufferElSizes[Idxs[buffer]];
|
||||
}
|
||||
|
||||
AACENC_BufDesc inBufDesc;
|
||||
inBufDesc.numBufs = kMaxBuffers;
|
||||
inBufDesc.bufs = (void **)&inBuffer;
|
||||
inBufDesc.bufferIdentifiers = inBufferIds;
|
||||
inBufDesc.bufSizes = inBufferSize;
|
||||
inBufDesc.bufElSizes = inBufferElSize;
|
||||
|
||||
uint8_t **outPtrRef = new uint8_t *[kMaxBuffers];
|
||||
for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
|
||||
outPtrRef[buffer] = new uint8_t[kMaxOutputBufferSize];
|
||||
}
|
||||
|
||||
void *outBuffer[kMaxBuffers];
|
||||
INT outBufferIds[kMaxBuffers];
|
||||
INT outBufferSize[kMaxBuffers];
|
||||
INT outBufferElSize[kMaxBuffers];
|
||||
|
||||
for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
|
||||
outBuffer[buffer] = outPtrRef[buffer];
|
||||
outBufferIds[buffer] = OUT_BITSTREAM_DATA;
|
||||
outBufferSize[buffer] = (INT)kMaxOutputBufferSize;
|
||||
outBufferElSize[buffer] = sizeof(UCHAR);
|
||||
}
|
||||
|
||||
AACENC_BufDesc outBufDesc;
|
||||
outBufDesc.numBufs = kMaxBuffers;
|
||||
outBufDesc.bufs = (void **)&outBuffer;
|
||||
outBufDesc.bufferIdentifiers = outBufferIds;
|
||||
outBufDesc.bufSizes = outBufferSize;
|
||||
outBufDesc.bufElSizes = outBufferElSize;
|
||||
|
||||
AACENC_OutArgs outargs = {};
|
||||
aacEncEncode(mEncoder, &inBufDesc, &outBufDesc, &inargs, &outargs);
|
||||
|
||||
if (outargs.numOutBytes == 0) {
|
||||
if (audioSize > 0) {
|
||||
++audioData;
|
||||
--audioSize;
|
||||
}
|
||||
if (ancSize > 0) {
|
||||
++ancData;
|
||||
--ancSize;
|
||||
}
|
||||
} else {
|
||||
size_t audioConsumed = outargs.numInSamples * sizeof(int16_t);
|
||||
audioData += audioConsumed;
|
||||
audioSize -= audioConsumed;
|
||||
|
||||
size_t ancConsumed = outargs.numAncBytes;
|
||||
ancData += ancConsumed;
|
||||
ancSize -= ancConsumed;
|
||||
}
|
||||
deleteBuffers(outPtrRef, kMaxBuffers);
|
||||
|
||||
// break out of loop if only metadata was sent in all the input buffers
|
||||
// as sending it multiple times in a loop is redundant.
|
||||
if ((mInBufferIdx_1 == kMaxBuffers - 1) && (mInBufferIdx_2 == kMaxBuffers - 1) &&
|
||||
(mInBufferIdx_3 == kMaxBuffers - 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Codec::deInitEncoder() { aacEncClose(&mEncoder); }
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
if (size < IDX_LAST) {
|
||||
return 0;
|
||||
}
|
||||
Codec encoder;
|
||||
if (encoder.initEncoder(const_cast<uint8_t **>(&data), &size)) {
|
||||
encoder.encodeFrames(data, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
|
@ -245,6 +245,46 @@ INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
|
|||
return bitrate;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
functionname: FDKaacEnc_AdjustVBRBitrateMode
|
||||
description: Adjust bitrate mode to given bitrate parameter
|
||||
input params: int vbrQuality (VBR0, VBR1, VBR2)
|
||||
bitrate
|
||||
channelMode
|
||||
returns: vbr bitrate mode
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
|
||||
AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode) {
|
||||
AACENC_BITRATE_MODE newBitrateMode = bitrateMode;
|
||||
|
||||
if (bitrate != -1) {
|
||||
const INT monoStereoMode =
|
||||
(FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) ? 1 : 0;
|
||||
const INT nChannelsEff =
|
||||
FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
|
||||
newBitrateMode = AACENC_BR_MODE_INVALID;
|
||||
|
||||
for (int idx = (int)(sizeof(configTabVBR) / sizeof(*configTabVBR)) - 1;
|
||||
idx >= 0; idx--) {
|
||||
if (bitrate >=
|
||||
configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff) {
|
||||
if (configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff <
|
||||
FDKaacEnc_GetVBRBitrate(bitrateMode, channelMode)) {
|
||||
newBitrateMode = configTabVBR[idx].bitrateMode;
|
||||
} else {
|
||||
newBitrateMode = bitrateMode;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AACENC_BR_MODE_IS_VBR(newBitrateMode) ? newBitrateMode
|
||||
: AACENC_BR_MODE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert encoder bitreservoir value for transport library.
|
||||
*
|
||||
|
@ -397,7 +437,6 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
|||
FIXP_DBL mbfac, bw_ratio;
|
||||
QC_INIT qcInit;
|
||||
INT averageBitsPerFrame = 0;
|
||||
int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
|
||||
const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
|
||||
|
||||
if (config == NULL) return AAC_ENC_INVALID_HANDLE;
|
||||
|
@ -553,7 +592,6 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
|||
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
|
||||
} else {
|
||||
INT bitreservoir = -1; /* default bitreservoir size*/
|
||||
bitresMin = BITRES_MIN;
|
||||
if (isLowDelay(config->audioObjectType)) {
|
||||
INT brPerChannel = config->bitRate / config->nChannels;
|
||||
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
|
||||
|
@ -567,7 +605,6 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
|||
bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
|
||||
BITRES_MIN_LD; /* interpolate */
|
||||
bitreservoir = bitreservoir & ~7; /* align to bytes */
|
||||
bitresMin = BITRES_MIN_LD;
|
||||
}
|
||||
|
||||
int maxBitres;
|
||||
|
@ -604,7 +641,8 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
|||
qcInit.nSubFrames = config->nSubFrames;
|
||||
qcInit.padding.paddingRest = config->sampleRate;
|
||||
|
||||
if (qcInit.maxBits - qcInit.averageBits >= bitresMin * config->nChannels) {
|
||||
if (qcInit.maxBits - qcInit.averageBits >=
|
||||
((qcInit.isLowDelay) ? BITRES_MIN_LD : BITRES_MIN) * config->nChannels) {
|
||||
qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
|
||||
} else if (qcInit.maxBits > qcInit.averageBits) {
|
||||
qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
|
@ -334,6 +334,19 @@ INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder);
|
|||
INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
|
||||
CHANNEL_MODE channelMode);
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
functionname: FDKaacEnc_AdjustVBRBitrateMode
|
||||
description: Adjust bitrate mode to given bitrate parameter
|
||||
input params: int vbrQuality (VBR0, VBR1, VBR2)
|
||||
bitrate
|
||||
channelMode
|
||||
returns: vbr bitrate mode
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
|
||||
AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode);
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
functionname: FDKaacEnc_AacInitDefaultConfig
|
||||
|
|
|
@ -1028,6 +1028,13 @@ static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
|
|||
case AACENC_BR_MODE_VBR_3:
|
||||
case AACENC_BR_MODE_VBR_4:
|
||||
case AACENC_BR_MODE_VBR_5:
|
||||
/* Adjust bitrate mode in case given peak bitrate is lower than expected
|
||||
* VBR bitrate. */
|
||||
if ((INT)config->userPeakBitrate != -1) {
|
||||
hAacConfig->bitrateMode = FDKaacEnc_AdjustVBRBitrateMode(
|
||||
hAacConfig->bitrateMode, config->userPeakBitrate,
|
||||
hAacConfig->channelMode);
|
||||
}
|
||||
/* Get bitrate in VBR configuration */
|
||||
/* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
|
@ -373,13 +373,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init,
|
|||
hQC->invQuant = init->invQuant;
|
||||
hQC->maxIterations = init->maxIterations;
|
||||
|
||||
if (isConstantBitrateMode(hQC->bitrateMode)) {
|
||||
/* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir
|
||||
*/
|
||||
hQC->bitResMode = init->bitResMode;
|
||||
} else {
|
||||
hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
|
||||
}
|
||||
/* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
|
||||
hQC->bitResMode = init->bitResMode;
|
||||
|
||||
hQC->padding.paddingRest = init->padding.paddingRest;
|
||||
|
||||
|
@ -800,10 +795,15 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
|
|||
INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
|
||||
INT totalAvailableBits = 0;
|
||||
INT nSubFrames = 1;
|
||||
const INT isCBRAdjustment = (isConstantBitrateMode(hQC->bitrateMode) ||
|
||||
(hQC->bitResMode != AACENC_BR_MODE_FULL))
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
/*-------------------------------------------- */
|
||||
/* redistribute total bitreservoir to elements */
|
||||
ErrorStatus = FDKaacEnc_BitResRedistribution(hQC, cm, avgTotalBits);
|
||||
ErrorStatus = FDKaacEnc_BitResRedistribution(
|
||||
hQC, cm, (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits);
|
||||
if (ErrorStatus != AAC_ENC_OK) {
|
||||
return ErrorStatus;
|
||||
}
|
||||
|
@ -831,33 +831,22 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
|
|||
|
||||
/*-------------------------------------------- */
|
||||
/*-------------------------------------------- */
|
||||
if (isConstantBitrateMode(hQC->bitrateMode)) {
|
||||
/* calc granted dynamic bits for sub frame and
|
||||
distribute it to each element */
|
||||
ErrorStatus = FDKaacEnc_prepareBitDistribution(
|
||||
hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits,
|
||||
&avgTotalDynBits);
|
||||
/* calc granted dynamic bits for sub frame and
|
||||
distribute it to each element */
|
||||
ErrorStatus = FDKaacEnc_prepareBitDistribution(
|
||||
hQC, psyOut, qcOut, cm, qcElement,
|
||||
(isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits,
|
||||
&totalAvailableBits, &avgTotalDynBits);
|
||||
|
||||
if (ErrorStatus != AAC_ENC_OK) {
|
||||
return ErrorStatus;
|
||||
}
|
||||
} else {
|
||||
qcOut[0]->grantedDynBits =
|
||||
((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) -
|
||||
(qcOut[0]->globalExtBits + qcOut[0]->staticBits +
|
||||
qcOut[0]->elementExtBits);
|
||||
qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits;
|
||||
|
||||
totalAvailableBits = hQC->maxBitsPerFrame;
|
||||
avgTotalDynBits = 0;
|
||||
if (ErrorStatus != AAC_ENC_OK) {
|
||||
return ErrorStatus;
|
||||
}
|
||||
|
||||
/* for ( all sub frames ) ... */
|
||||
for (c = 0; c < nSubFrames; c++) {
|
||||
/* for CBR and VBR mode */
|
||||
FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
|
||||
psyOut[c]->psyOutElement,
|
||||
isConstantBitrateMode(hQC->bitrateMode), cm);
|
||||
psyOut[c]->psyOutElement, isCBRAdjustment, cm);
|
||||
|
||||
} /* -end- sub frame counter */
|
||||
|
||||
|
|
Loading…
Reference in New Issue