aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp52
-rw-r--r--METADATA3
-rw-r--r--fuzzer/Android.bp82
-rw-r--r--fuzzer/README.md150
-rw-r--r--fuzzer/aac_dec_fuzzer.cpp141
-rw-r--r--fuzzer/aac_enc_fuzzer.cpp479
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp19
-rw-r--r--libAACenc/src/aacenc_lib.cpp13
-rw-r--r--libDRCdec/src/FDK_drcDecLib.cpp2
-rw-r--r--libFDK/src/FDK_core.cpp2
-rw-r--r--libMpegTPDec/src/tpdec_asc.cpp45
-rw-r--r--libMpegTPDec/src/tpdec_lib.cpp2
-rw-r--r--libMpegTPEnc/src/tpenc_lib.cpp2
-rw-r--r--libPCMutils/src/version.h2
-rw-r--r--libSACdec/src/sac_dec_lib.cpp2
-rw-r--r--libSACenc/src/sacenc_lib.cpp2
-rw-r--r--libSBRdec/src/sbrdecoder.cpp2
-rw-r--r--libSBRenc/src/env_est.cpp22
-rw-r--r--libSBRenc/src/sbr_encoder.cpp7
19 files changed, 993 insertions, 36 deletions
diff --git a/Android.bp b/Android.bp
index 1cf54fd..0c67186 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,6 +1,40 @@
+// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
+// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
+// DEPENDING ON IT IN YOUR PROJECT. ***
+package {
+ default_applicable_licenses: ["external_aac_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "external_aac_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "legacy_by_exception_only", // by exception only
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_library_static {
name: "libFraunhoferAAC",
vendor_available: true,
+ host_supported: true,
srcs: [
"libAACdec/src/*.cpp",
"libAACenc/src/*.cpp",
@@ -23,15 +57,15 @@ cc_library_static {
"-Wuninitialized",
"-Wno-self-assign",
"-Wno-implicit-fallthrough",
+ "-DSUPPRESS_BUILD_DATE_INFO",
],
sanitize: {
- misc_undefined:[
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- "bounds",
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ "bounds",
],
- // Enable CFI if this becomes a shared library.
- // cfi: true,
+ cfi: true,
},
shared_libs: [
"liblog",
@@ -52,6 +86,12 @@ cc_library_static {
"libSACenc/include",
],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
apex_available: [
"//apex_available:platform",
"com.android.bluetooth.updatable",
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..5c12860
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: BY_EXCEPTION_ONLY
+}
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..6739798
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * 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
+ */
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_aac_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_aac_license"],
+}
+
+cc_defaults {
+ name: "aac_fuzz_defaults",
+ host_supported: true,
+
+ static_libs: [
+ "libFraunhoferAAC",
+ ],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ 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"
+ ],
+
+ include_dirs: [
+ "external/aac/libAACenc/"
+ ],
+}
diff --git a/fuzzer/README.md b/fuzzer/README.md
new file mode 100644
index 0000000..b8cc260
--- /dev/null
+++ b/fuzzer/README.md
@@ -0,0 +1,150 @@
+# Fuzzer for libFraunhoferAAC decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for aac decoder is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+
+This fuzzer makes use of the following config parameters:
+1. Transport type (parameter name: `TRANSPORT_TYPE`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `TRANSPORT_TYPE` | 0.`TT_UNKNOWN ` 1.`TT_MP4_RAW ` 2.`TT_MP4_ADIF ` 3.`TT_MP4_ADTS ` 4.`TT_MP4_LATM_MCP1 ` 5.`TT_MP4_LATM_MCP0 ` 6.`TT_MP4_LOAS ` 7.`TT_DRM ` | `TT_MP4_ADIF ` |
+
+Note: Value of `TRANSPORT_TYPE` could be set to any of these values.
+It is set to `TT_MP4_ADIF` in the fuzzer plugin.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by an
+ offset calculated using valid bytes.
+ * If the decode operation was un-successful, the input is advanced by 1 byte
+ till it reaches a valid frame or end of stream.
+
+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_dec_fuzzer binary.
+
+## Android
+
+### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) aac_dec_fuzzer
+```
+
+### Steps to run
+Create a directory CORPUS_DIR and copy some aac files to that folder.
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
+```
+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:
+
+| AACENC_PARAM param| Valid Values| Configured Value|
+|-------------| ----- |----- |
+|`AACENC_SBR_MODE` | `-1 ` `0 ` `1 ` `2 ` | Calculated using first byte of data |
+|`AACENC_AOT` |`AOT_NONE ` `AOT_NULL_OBJECT ` `AOT_AAC_MAIN ` `AOT_AAC_LC ` `AOT_AAC_SSR ` `AOT_AAC_LTP ` `AOT_SBR ` `AOT_AAC_SCAL ` `AOT_TWIN_VQ ` `AOT_CELP ` `AOT_HVXC ` `AOT_RSVD_10 ` `AOT_RSVD_11 ` `AOT_TTSI ` `AOT_MAIN_SYNTH ` `AOT_WAV_TAB_SYNTH ` `AOT_GEN_MIDI ` `AOT_ALG_SYNTH_AUD_FX ` `AOT_ER_AAC_LC ` `AOT_RSVD_18 ` `AOT_ER_AAC_LTP ` `AOT_ER_AAC_SCAL ` `AOT_ER_TWIN_VQ ` `AOT_ER_BSAC ` `AOT_ER_AAC_LD ` `AOT_ER_CELP ` `AOT_ER_HVXC ` `AOT_ER_HILN ` `AOT_ER_PARA ` `AOT_RSVD_28 ` `AOT_PS ` `AOT_MPEGS ` `AOT_ESCAPE ` `AOT_MP3ONMP4_L1 ` `AOT_MP3ONMP4_L2 ` `AOT_MP3ONMP4_L3 ` `AOT_RSVD_35 ` `AOT_RSVD_36 ` `AOT_AAC_SLS ` `AOT_SLS ` `AOT_ER_AAC_ELD ` `AOT_USAC ` `AOT_SAOC ` `AOT_LD_MPEGS ` `AOT_MP2_AAC_LC ` `AOT_MP2_SBR ` `AOT_DRM_AAC ` `AOT_DRM_SBR ` `AOT_DRM_MPEG_PS ` `AOT_DRM_SURROUND ` `AOT_DRM_USAC ` | Calculated using second byte of data |
+|`AACENC_SAMPLERATE` | `8000 ` `11025 ` `12000 ` `16000 ` `22050 ` `24000 ` `32000 ` `44100 ` `48000 ` `64000 ` `88200 ` `96000 `| Calculated using third byte of data |
+|`AACENC_BITRATE` | In range `8000 ` to `960000 ` | Calculated using fourth, fifth and sixth byte of data |
+|`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_6_1 ` `MODE_7_1_BACK ` `MODE_7_1_TOP_FRONT ` `MODE_7_1_REAR_SURROUND ` `MODE_7_1_FRONT_CENTER ` `MODE_212 ` | Calculated using seventh byte of data |
+|`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 |`AACENC_SBR_RATIO` |`-1 ` `0 ` `1 ` `2 ` | Calculated using ninth byte of data |
+|`AACENC_BITRATEMODE` |`AACENC_BR_MODE_INVALID ` `AACENC_BR_MODE_CBR ` `AACENC_BR_MODE_VBR_1 ` `AACENC_BR_MODE_VBR_2 ` `AACENC_BR_MODE_VBR_3 ` `AACENC_BR_MODE_VBR_4 ` `AACENC_BR_MODE_VBR_5 ` `AACENC_BR_MODE_FF ` `AACENC_BR_MODE_SFR ` | Calculated using thirty-fourth byte of data |
+|`AACENC_GRANULE_LENGTH` |`120 ` `128 ` `240 ` `256 ` `480 ` `512 ` `1024 ` | Calculated using thirty-fifth byte of data |
+|`AACENC_CHANNELORDER` |`CH_ORDER_MPEG ` `CH_ORDER_WAV ` | Calculated using thirty-sixth byte of data |
+|`AACENC_AFTERBURNER` |`0 ` `1 ` | Calculated using thirty-seventh byte of data |
+|`AACENC_BANDWIDTH` |`0 ` `1` | Calculated using thirty-eigth byte of data |
+|` AACENC_IDX_PEAK_BITRATE` | In range `8000 ` to `960000 ` | Calculated using thirty-ninth byte of data |
+|` AACENC_HEADER_PERIOD` |In range `0 ` to `255 ` | Calculated using fortieth byte of data |
+|` AACENC_SIGNALING_MODE` |`-1 ` `0 ` `1 ` `2 ` `3 ` | Calculated using forty-first byte of data |
+|` AACENC_TPSUBFRAMES` |In range `0 ` to `255 ` | Calculated using forty-second byte of data |
+|` AACENC_AUDIOMUXVER` |`-1 ` `0 ` `1 ` `2 ` | Calculated using forty-third byte of data |
+|` AACENC_PROTECTION` |`0 ` `1 ` | Calculated using forty-fourth of data |
+|`AACENC_ANCILLARY_BITRATE` |In range `0 ` to `960000 `| Calculated using forty-fifth byte of data |
+|`AACENC_METADATA_MODE ` |`0 ` `1 ` `2 ` `3 ` | Calculated using forty-sixth 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
diff --git a/fuzzer/aac_dec_fuzzer.cpp b/fuzzer/aac_dec_fuzzer.cpp
new file mode 100644
index 0000000..c970197
--- /dev/null
+++ b/fuzzer/aac_dec_fuzzer.cpp
@@ -0,0 +1,141 @@
+/******************************************************************************
+ *
+ * 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 <stdint.h>
+#include <string.h>
+#include <algorithm>
+#include "aacdecoder_lib.h"
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+constexpr uint32_t kMaxConfigurationSize = 1024;
+constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
+
+// Value indicating the start of AAC Header Segment
+constexpr const char *kAacSegStartSeq = "AAC_STRT";
+constexpr uint8_t kAacSegStartSeqLen = sizeof(kAacSegStartSeq);
+// Value indicating the end of AAC Header Segment
+constexpr const char *kAacSegEndSeq = "AAC_ENDS";
+constexpr uint8_t kAacSegEndSeqLen = sizeof(kAacSegEndSeq);
+
+// Number of bytes used to signal the length of the header
+constexpr uint8_t kHeaderLengthBytes = 2;
+// Minimum size of an AAC header is 2
+// Minimum data required is
+// strlen(AAC_STRT) + strlen(AAC_ENDS) + kHeaderLengthBytes + 2;
+constexpr UINT kMinDataSize = kAacSegStartSeqLen + kAacSegEndSeqLen + kHeaderLengthBytes + 2;
+
+UINT getHeaderSize(UCHAR *data, UINT size) {
+ if (size < kMinDataSize) {
+ return 0;
+ }
+
+ int32_t result = memcmp(data, kAacSegStartSeq, kAacSegStartSeqLen);
+ if (result) {
+ return 0;
+ }
+ data += kAacSegStartSeqLen;
+ size -= kAacSegStartSeqLen;
+
+ uint32_t headerLengthInBytes = (data[0] << 8 | data[1]) & 0xFFFF;
+ data += kHeaderLengthBytes;
+ size -= kHeaderLengthBytes;
+
+ if (headerLengthInBytes + kAacSegEndSeqLen > size) {
+ return 0;
+ }
+
+ data += headerLengthInBytes;
+ size -= headerLengthInBytes;
+ result = memcmp(data, kAacSegEndSeq, kAacSegEndSeqLen);
+ if (result) {
+ return 0;
+ }
+
+ return std::min(headerLengthInBytes, kMaxConfigurationSize);
+}
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(UCHAR *data, UINT size);
+ void deInitDecoder();
+
+ private:
+ HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+ AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+};
+
+bool Codec::initDecoder() {
+ mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
+ if (!mAacDecoderHandle) {
+ return false;
+ }
+ return true;
+}
+
+void Codec::deInitDecoder() {
+ aacDecoder_Close(mAacDecoderHandle);
+ mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+ UINT headerSize = getHeaderSize(data, size);
+ if (headerSize != 0) {
+ data += kAacSegStartSeqLen + kHeaderLengthBytes;
+ size -= kAacSegStartSeqLen + kHeaderLengthBytes;
+ aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &headerSize);
+ data += headerSize + kAacSegEndSeqLen;
+ size -= headerSize + kAacSegEndSeqLen;
+ }
+ while (size > 0) {
+ UINT inputSize = size;
+ UINT valid = size;
+ mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+ if (mErrorCode != AAC_DEC_OK) {
+ ++data;
+ --size;
+ } else {
+ INT_PCM outputBuf[kMaxOutBufferSize];
+ do {
+ mErrorCode =
+ aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
+ kMaxOutBufferSize /*size in number of INT_PCM, not bytes*/, 0);
+ } while (mErrorCode == AAC_DEC_OK);
+ UINT offset = inputSize - valid;
+ data += offset;
+ size = valid;
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder()) {
+ codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
+ }
+ delete codec;
+ return 0;
+}
diff --git a/fuzzer/aac_enc_fuzzer.cpp b/fuzzer/aac_enc_fuzzer.cpp
new file mode 100644
index 0000000..5a35d70
--- /dev/null
+++ b/fuzzer/aac_enc_fuzzer.cpp
@@ -0,0 +1,479 @@
+/******************************************************************************
+ *
+ * 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"
+#include "src/aacenc.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 int32_t kSampleRates[] = {8000, 11025, 12000, 16000, 22050, 24000,
+ 32000, 44100, 48000, 64000, 88200, 96000};
+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_6_1,
+ MODE_7_1_BACK,
+ MODE_7_1_TOP_FRONT,
+ MODE_7_1_REAR_SURROUND,
+ MODE_7_1_FRONT_CENTER,
+ MODE_212};
+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_NONE, AOT_NULL_OBJECT,
+ AOT_AAC_MAIN, AOT_AAC_LC,
+ AOT_AAC_SSR, AOT_AAC_LTP,
+ AOT_SBR, AOT_AAC_SCAL,
+ AOT_TWIN_VQ, AOT_CELP,
+ AOT_HVXC, AOT_RSVD_10,
+ AOT_RSVD_11, AOT_TTSI,
+ AOT_MAIN_SYNTH, AOT_WAV_TAB_SYNTH,
+ AOT_GEN_MIDI, AOT_ALG_SYNTH_AUD_FX,
+ AOT_ER_AAC_LC, AOT_RSVD_18,
+ AOT_ER_AAC_LTP, AOT_ER_AAC_SCAL,
+ AOT_ER_TWIN_VQ, AOT_ER_BSAC,
+ AOT_ER_AAC_LD, AOT_ER_CELP,
+ AOT_ER_HVXC, AOT_ER_HILN,
+ AOT_ER_PARA, AOT_RSVD_28,
+ AOT_PS, AOT_MPEGS,
+ AOT_ESCAPE, AOT_MP3ONMP4_L1,
+ AOT_MP3ONMP4_L2, AOT_MP3ONMP4_L3,
+ AOT_RSVD_35, AOT_RSVD_36,
+ AOT_AAC_SLS, AOT_SLS,
+ AOT_ER_AAC_ELD, AOT_USAC,
+ AOT_SAOC, AOT_LD_MPEGS,
+ AOT_MP2_AAC_LC, AOT_MP2_SBR,
+ AOT_DRM_AAC, AOT_DRM_SBR,
+ AOT_DRM_MPEG_PS, AOT_DRM_SURROUND,
+ AOT_DRM_USAC};
+
+constexpr size_t kAudioObjectTypesSize = size(kAudioObjectTypes);
+
+constexpr int32_t kSbrRatios[] = {-1, 0, 1, 2};
+constexpr size_t kSbrRatiosSize = size(kSbrRatios);
+
+constexpr int32_t kBitRateModes[] = {
+ AACENC_BR_MODE_INVALID, AACENC_BR_MODE_CBR, AACENC_BR_MODE_VBR_1,
+ AACENC_BR_MODE_VBR_2, AACENC_BR_MODE_VBR_3, AACENC_BR_MODE_VBR_4,
+ AACENC_BR_MODE_VBR_5, AACENC_BR_MODE_FF, AACENC_BR_MODE_SFR};
+constexpr size_t kBitRateModesSize = size(kBitRateModes);
+
+constexpr int32_t kGranuleLengths[] = {120, 128, 240, 256, 480, 512, 1024};
+constexpr size_t kGranuleLengthsSize = size(kGranuleLengths);
+
+constexpr int32_t kChannelOrder[] = {CH_ORDER_MPEG, CH_ORDER_WAV};
+constexpr size_t kChannelOrderSize = size(kChannelOrder);
+
+constexpr int32_t kSignalingModes[] = {-1, 0, 1, 2, 3};
+constexpr size_t kSignalingModesSize = size(kSignalingModes);
+
+constexpr int32_t kAudioMuxVer[] = {-1, 0, 1, 2};
+constexpr size_t kAudioMuxVerSize = size(kAudioMuxVer);
+
+constexpr int32_t kSbrModes[] = {-1, 0, 1, 2};
+constexpr size_t kSbrModesSize = size(kSbrModes);
+
+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_BIT_RATE_MODE,
+ IDX_GRANULE_LENGTH,
+ IDX_CHANNELORDER,
+ IDX_AFTERBURNER,
+ IDX_BANDWIDTH,
+ IDX_PEAK_BITRATE,
+ IDX_HEADER_PERIOD,
+ IDX_SIGNALING_MODE,
+ IDX_TPSUBFRAMES,
+ IDX_AUDIOMUXVER,
+ IDX_PROTECTION,
+ IDX_ANCILLARY_BITRATE,
+ IDX_METADATA_MODE,
+ IDX_LAST
+};
+
+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:
+ template <typename type1, typename type2, typename type3>
+ void setAACParam(type1 data, const AACENC_PARAM aacParam, type2 min, type2 max,
+ const type3 *array = nullptr);
+ 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;
+}
+
+template <typename type1, typename type2, typename type3>
+void Codec::setAACParam(type1 data, const AACENC_PARAM aacParam, type2 min, type2 max,
+ const type3 *array) {
+ auto value = 0;
+ if (array) {
+ uint32_t index = generateNumberInRangeFromData(data, min, max);
+ value = array[index];
+ } else {
+ value = generateNumberInRangeFromData(data, min, max);
+ }
+ aacEncoder_SetParam(mEncoder, aacParam, value);
+ (void)aacEncoder_GetParam(mEncoder, aacParam);
+}
+
+bool Codec::initEncoder(uint8_t **dataPtr, size_t *sizePtr) {
+ uint8_t *data = *dataPtr;
+
+ if (AACENC_OK != aacEncOpen(&mEncoder, 0, 0)) {
+ return false;
+ }
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_SBR_MODE], AACENC_SBR_MODE, 0, kSbrModesSize - 1,
+ kSbrModes);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_SBR_RATIO], AACENC_SBR_RATIO, 0,
+ kSbrRatiosSize - 1, kSbrRatios);
+
+ setAACParam<uint8_t, size_t, AUDIO_OBJECT_TYPE>(data[IDX_AAC_AOT], AACENC_AOT, 0,
+ kAudioObjectTypesSize - 1, kAudioObjectTypes);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_SAMPLE_RATE], AACENC_SAMPLERATE, 0,
+ kSampleRatesSize - 1, kSampleRates);
+
+ uint32_t tempValue =
+ (data[IDX_BIT_RATE_1] << 16) | (data[IDX_BIT_RATE_2] << 8) | data[IDX_BIT_RATE_3];
+ setAACParam<uint8_t, uint32_t, uint32_t>(tempValue, AACENC_BITRATE, kMinBitRate, kMaxBitRate);
+
+ setAACParam<uint8_t, size_t, CHANNEL_MODE>(data[IDX_CHANNEL], AACENC_CHANNELMODE, 0,
+ kChannelModesSize - 1, kChannelModes);
+
+ setAACParam<uint8_t, size_t, TRANSPORT_TYPE>(data[IDX_IDENTIFIER], AACENC_TRANSMUX, 0,
+ kIdentifiersSize - 1, kIdentifiers);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_BIT_RATE_MODE], AACENC_BITRATEMODE, 0,
+ kBitRateModesSize - 1, kBitRateModes);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_GRANULE_LENGTH], AACENC_GRANULE_LENGTH, 0,
+ kGranuleLengthsSize - 1, kGranuleLengths);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_CHANNELORDER], AACENC_CHANNELORDER, 0,
+ kChannelOrderSize - 1, kChannelOrder);
+
+ setAACParam<uint8_t, int32_t, int32_t>(data[IDX_AFTERBURNER], AACENC_AFTERBURNER, 0, 1);
+
+ setAACParam<uint8_t, int32_t, int32_t>(data[IDX_BANDWIDTH], AACENC_BANDWIDTH, 0, 1);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_PEAK_BITRATE], AACENC_PEAK_BITRATE,
+ kMinBitRate, kMinBitRate);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_HEADER_PERIOD], AACENC_HEADER_PERIOD, 0,
+ UINT8_MAX);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_SIGNALING_MODE], AACENC_SIGNALING_MODE, 0,
+ kSignalingModesSize - 1, kSignalingModes);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_TPSUBFRAMES], AACENC_TPSUBFRAMES, 0,
+ UINT8_MAX);
+
+ setAACParam<uint8_t, size_t, int32_t>(data[IDX_AUDIOMUXVER], AACENC_AUDIOMUXVER, 0,
+ kAudioMuxVerSize - 1, kAudioMuxVer);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_PROTECTION], AACENC_PROTECTION, 0, 1);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_ANCILLARY_BITRATE], AACENC_ANCILLARY_BITRATE,
+ 0, kMaxBitRate);
+
+ setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_METADATA_MODE], AACENC_METADATA_MODE, 0, 3);
+
+ AACENC_InfoStruct encInfo;
+ aacEncInfo(mEncoder, &encInfo);
+
+ 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;
+}
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 90563ea..9d36d10 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -122,7 +122,7 @@ amm-info@iis.fraunhofer.de
#define AACDECODER_LIB_VL1 2
#define AACDECODER_LIB_VL2 0
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define AACDECODER_LIB_BUILD_DATE ""
#define AACDECODER_LIB_BUILD_TIME ""
#else
@@ -441,12 +441,23 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
TRANSPORTDEC_ERROR errTp;
HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+ UCHAR dummyBuffer[4] = {0};
+ FDK_BITSTREAM dummyBs;
+ HANDLE_FDK_BITSTREAM hReadBs;
if (subStreamIndex != 0) {
return TRANSPORTDEC_OK;
}
- else if (aot == AOT_USAC) {
+ if (hBs == NULL) {
+ /* use dummy zero payload to clear memory */
+ hReadBs = &dummyBs;
+ FDKinitBitStream(hReadBs, dummyBuffer, 4, 24);
+ } else {
+ hReadBs = hBs;
+ }
+
+ if (aot == AOT_USAC) {
drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
}
@@ -455,10 +466,10 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
if (payloadType == 0) /* uniDrcConfig */
{
- err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs);
+ err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hReadBs);
} else /* loudnessInfoSet */
{
- err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs);
+ err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hReadBs);
hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
}
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index 3bfdfe8..caa62c5 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de
#define AACENCODER_LIB_VL1 0
#define AACENCODER_LIB_VL2 1
#define AACENCODER_LIB_TITLE "AAC Encoder"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define AACENCODER_LIB_BUILD_DATE ""
#define AACENCODER_LIB_BUILD_TIME ""
#else
@@ -1827,12 +1827,13 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
/* clear out until end-of-buffer */
if (nZeros) {
+ INT_PCM *pIn =
+ hAacEncoder->inputBuffer +
+ hAacEncoder->inputBufferOffset /
+ hAacEncoder->aacConfig.nChannels +
+ hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
- FDKmemclear(hAacEncoder->inputBuffer +
- i * hAacEncoder->inputBufferSizePerChannel +
- (hAacEncoder->inputBufferOffset +
- hAacEncoder->nSamplesRead) /
- hAacEncoder->extParam.nChannels,
+ FDKmemclear(pIn + i * hAacEncoder->inputBufferSizePerChannel,
sizeof(INT_PCM) * nZeros);
}
hAacEncoder->nZerosAppended += nZeros;
diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp
index 83b5773..26e5b78 100644
--- a/libDRCdec/src/FDK_drcDecLib.cpp
+++ b/libDRCdec/src/FDK_drcDecLib.cpp
@@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de
#define DRCDEC_LIB_VL1 1
#define DRCDEC_LIB_VL2 0
#define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define DRCDEC_LIB_BUILD_DATE ""
#define DRCDEC_LIB_BUILD_TIME ""
#else
diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp
index 2f77179..48db17e 100644
--- a/libFDK/src/FDK_core.cpp
+++ b/libFDK/src/FDK_core.cpp
@@ -107,7 +107,7 @@ amm-info@iis.fraunhofer.de
#define FDK_TOOLS_LIB_VL1 1
#define FDK_TOOLS_LIB_VL2 0
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define FDK_TOOLS_LIB_BUILD_DATE ""
#define FDK_TOOLS_LIB_BUILD_TIME ""
#else
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp
index a2baaaf..e46cb32 100644
--- a/libMpegTPDec/src/tpdec_asc.cpp
+++ b/libMpegTPDec/src/tpdec_asc.cpp
@@ -1778,6 +1778,10 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
int numConfigExtensions;
CONFIG_EXT_ID usacConfigExtType;
int usacConfigExtLength;
+ int loudnessInfoSetIndex =
+ -1; /* index of loudnessInfoSet config extension. -1 if not contained. */
+ int tmp_subStreamIndex = 0;
+ AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC;
numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
@@ -1807,10 +1811,12 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
cb->cbUniDrcData, hBs, usacConfigExtLength,
1, /* loudnessInfoSet */
- 0, loudnessInfoSetConfigExtensionPosition, AOT_USAC);
+ tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition,
+ tmp_aot);
if (ErrorStatus != TRANSPORTDEC_OK) {
return ErrorStatus;
}
+ loudnessInfoSetIndex = confExtIdx;
}
} break;
default:
@@ -1826,6 +1832,17 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
FDKpushFor(hBs, usacConfigExtLength);
}
+ if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) {
+ /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
+ * an empty config extension */
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex,
+ 0, tmp_aot);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+
return ErrorStatus;
}
@@ -1842,6 +1859,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
int channelElementIdx =
0; /* index for elements which contain audio channels (sce, cpe, lfe) */
SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};
+ int uniDrcElement =
+ -1; /* index of uniDrc extension element. -1 if not contained. */
numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
usc->m_usacNumElements = numberOfElements;
@@ -2017,6 +2036,10 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
case ID_USAC_EXT:
ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
asc->m_samplesPerFrame, 0, asc->m_aot);
+ if (usc->element[i].extElement.usacExtElementType ==
+ ID_EXT_ELE_UNI_DRC) {
+ uniDrcElement = i;
+ }
if (ErrorStatus) {
return ErrorStatus;
@@ -2045,6 +2068,18 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
}
}
+ if (uniDrcElement == -1 && cb->cbUniDrc != NULL) {
+ /* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an
+ * empty extension element */
+ int subStreamIndex = 0;
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0,
+ asc->m_aot);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+
return ErrorStatus;
}
@@ -2131,6 +2166,14 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
if (err != TRANSPORTDEC_OK) {
return err;
}
+ } else if (cb->cbUniDrc != NULL) {
+ /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
+ * an empty config extension */
+ err = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
}
/* sanity check whether number of channels signaled in UsacDecoderConfig()
diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp
index ca35184..091d011 100644
--- a/libMpegTPDec/src/tpdec_lib.cpp
+++ b/libMpegTPDec/src/tpdec_lib.cpp
@@ -1769,7 +1769,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
info += i;
info->module_id = FDK_TPDEC;
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else
diff --git a/libMpegTPEnc/src/tpenc_lib.cpp b/libMpegTPEnc/src/tpenc_lib.cpp
index 14ea5fe..77c19b5 100644
--- a/libMpegTPEnc/src/tpenc_lib.cpp
+++ b/libMpegTPEnc/src/tpenc_lib.cpp
@@ -647,7 +647,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
info->module_id = FDK_TPENC;
info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
LIB_VERSION_STRING(info);
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else
diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h
index 05371f8..871aa90 100644
--- a/libPCMutils/src/version.h
+++ b/libPCMutils/src/version.h
@@ -108,7 +108,7 @@ amm-info@iis.fraunhofer.de
#define PCMUTIL_LIB_VL1 1
#define PCMUTIL_LIB_VL2 0
#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define PCMUTIL_LIB_BUILD_DATE ""
#define PCMUTIL_LIB_BUILD_TIME ""
#else
diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp
index da19bb8..d30131f 100644
--- a/libSACdec/src/sac_dec_lib.cpp
+++ b/libSACdec/src/sac_dec_lib.cpp
@@ -1819,7 +1819,7 @@ int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
info += i;
info->module_id = FDK_MPSDEC;
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else
diff --git a/libSACenc/src/sacenc_lib.cpp b/libSACenc/src/sacenc_lib.cpp
index d6a1658..fcfe39b 100644
--- a/libSACenc/src/sacenc_lib.cpp
+++ b/libSACenc/src/sacenc_lib.cpp
@@ -130,7 +130,7 @@ Description of file contents
#define SACENC_LIB_VL1 0
#define SACENC_LIB_VL2 0
#define SACENC_LIB_TITLE "MPEG Surround Encoder"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define SACENC_LIB_BUILD_DATE ""
#define SACENC_LIB_BUILD_TIME ""
#else
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index 55f929f..b101a4a 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -158,7 +158,7 @@ amm-info@iis.fraunhofer.de
#define SBRDECODER_LIB_VL1 1
#define SBRDECODER_LIB_VL2 0
#define SBRDECODER_LIB_TITLE "SBR Decoder"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define SBRDECODER_LIB_BUILD_DATE ""
#define SBRDECODER_LIB_BUILD_TIME ""
#else
diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp
index 0eb8425..cc8780a 100644
--- a/libSBRenc/src/env_est.cpp
+++ b/libSBRenc/src/env_est.cpp
@@ -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
@@ -1267,6 +1267,7 @@ void FDKsbrEnc_extractSbrEnvelope2(
sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
+ hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF;
/*
Check if the current frame is divided into one envelope only. If so, set
@@ -1274,8 +1275,9 @@ void FDKsbrEnc_extractSbrEnvelope2(
*/
if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
(ed->nEnvelopes == 1)) {
+ AMP_RES currentAmpResFF = SBR_AMP_RES_1_5;
if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
- /* Note: global_tonaliy_float_value ==
+ /* Note: global_tonality_float_value ==
((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
threshold_float_value ==
((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0)));
@@ -1289,14 +1291,13 @@ void FDKsbrEnc_extractSbrEnvelope2(
} else {
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
}
- } else
- hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
+ currentAmpResFF = hEnvChan->encEnvData.currentAmpResFF;
+ }
- if (hEnvChan->encEnvData.currentAmpResFF !=
- hEnvChan->encEnvData.init_sbr_amp_res) {
+ if (currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
FDKsbrEnc_InitSbrHuffmanTables(
&hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
- &hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF);
+ &hEnvChan->sbrCodeNoiseFloor, currentAmpResFF);
}
} else {
if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
@@ -1355,6 +1356,13 @@ void FDKsbrEnc_extractSbrEnvelope2(
}
}
+ if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY &&
+ stereoMode == SBR_SWITCH_LRC &&
+ h_envChan[0]->encEnvData.currentAmpResFF !=
+ h_envChan[1]->encEnvData.currentAmpResFF) {
+ stereoMode = SBR_LEFT_RIGHT;
+ }
+
/*
Extract envelope of current frame.
*/
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp
index df9e996..c3da072 100644
--- a/libSBRenc/src/sbr_encoder.cpp
+++ b/libSBRenc/src/sbr_encoder.cpp
@@ -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
@@ -1450,8 +1450,6 @@ static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
params->deltaTAcrossFrames, 0, 0))
return (1);
- sbrConfigData->initAmpResFF = params->init_amp_res_FF;
-
if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope,
&hEnv->sbrCodeNoiseFloor,
sbrHeaderData->sbr_amp_res))
@@ -1749,6 +1747,7 @@ static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement,
hSbrElement->sbrHeaderData.sbr_data_extra = 1;
hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res;
+ hSbrElement->sbrConfigData.initAmpResFF = params->init_amp_res_FF;
/* header_extra_1 */
hSbrElement->sbrHeaderData.freqScale = params->freqScale;
@@ -2560,7 +2559,7 @@ INT sbrEncoder_GetLibInfo(LIB_INFO *info) {
info->version =
LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
LIB_VERSION_STRING(info);
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else