1*e5436536SAndroid Build Coastguard Worker /******************************************************************************
2*e5436536SAndroid Build Coastguard Worker *
3*e5436536SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
4*e5436536SAndroid Build Coastguard Worker *
5*e5436536SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*e5436536SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*e5436536SAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*e5436536SAndroid Build Coastguard Worker *
9*e5436536SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*e5436536SAndroid Build Coastguard Worker *
11*e5436536SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*e5436536SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*e5436536SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*e5436536SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*e5436536SAndroid Build Coastguard Worker * limitations under the License.
16*e5436536SAndroid Build Coastguard Worker *
17*e5436536SAndroid Build Coastguard Worker *****************************************************************************
18*e5436536SAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*e5436536SAndroid Build Coastguard Worker */
20*e5436536SAndroid Build Coastguard Worker
21*e5436536SAndroid Build Coastguard Worker #include <string>
22*e5436536SAndroid Build Coastguard Worker #include "aacenc_lib.h"
23*e5436536SAndroid Build Coastguard Worker #include "src/aacenc.h"
24*e5436536SAndroid Build Coastguard Worker
25*e5436536SAndroid Build Coastguard Worker using namespace std;
26*e5436536SAndroid Build Coastguard Worker
27*e5436536SAndroid Build Coastguard Worker // IN_AUDIO_DATA, IN_ANCILLRY_DATA and IN_METADATA_SETUP
28*e5436536SAndroid Build Coastguard Worker constexpr size_t kMaxBuffers = 3;
29*e5436536SAndroid Build Coastguard Worker
30*e5436536SAndroid Build Coastguard Worker constexpr size_t kMaxOutputBufferSize = 8192;
31*e5436536SAndroid Build Coastguard Worker
32*e5436536SAndroid Build Coastguard Worker constexpr uint32_t kMinBitRate = 8000;
33*e5436536SAndroid Build Coastguard Worker constexpr uint32_t kMaxBitRate = 960000;
34*e5436536SAndroid Build Coastguard Worker
35*e5436536SAndroid Build Coastguard Worker constexpr int32_t kSampleRates[] = {8000, 11025, 12000, 16000, 22050, 24000,
36*e5436536SAndroid Build Coastguard Worker 32000, 44100, 48000, 64000, 88200, 96000};
37*e5436536SAndroid Build Coastguard Worker constexpr size_t kSampleRatesSize = size(kSampleRates);
38*e5436536SAndroid Build Coastguard Worker
39*e5436536SAndroid Build Coastguard Worker constexpr CHANNEL_MODE kChannelModes[] = {MODE_1,
40*e5436536SAndroid Build Coastguard Worker MODE_2,
41*e5436536SAndroid Build Coastguard Worker MODE_1_2,
42*e5436536SAndroid Build Coastguard Worker MODE_1_2_1,
43*e5436536SAndroid Build Coastguard Worker MODE_1_2_2,
44*e5436536SAndroid Build Coastguard Worker MODE_1_2_2_1,
45*e5436536SAndroid Build Coastguard Worker MODE_1_2_2_2_1,
46*e5436536SAndroid Build Coastguard Worker MODE_6_1,
47*e5436536SAndroid Build Coastguard Worker MODE_7_1_BACK,
48*e5436536SAndroid Build Coastguard Worker MODE_7_1_TOP_FRONT,
49*e5436536SAndroid Build Coastguard Worker MODE_7_1_REAR_SURROUND,
50*e5436536SAndroid Build Coastguard Worker MODE_7_1_FRONT_CENTER,
51*e5436536SAndroid Build Coastguard Worker MODE_212};
52*e5436536SAndroid Build Coastguard Worker constexpr size_t kChannelModesSize = size(kChannelModes);
53*e5436536SAndroid Build Coastguard Worker
54*e5436536SAndroid Build Coastguard Worker constexpr TRANSPORT_TYPE kIdentifiers[] = {
55*e5436536SAndroid Build Coastguard Worker TT_MP4_RAW, TT_MP4_ADIF, TT_MP4_ADTS, TT_MP4_LATM_MCP1, TT_MP4_LATM_MCP0, TT_MP4_LOAS, TT_DRM};
56*e5436536SAndroid Build Coastguard Worker constexpr size_t kIdentifiersSize = size(kIdentifiers);
57*e5436536SAndroid Build Coastguard Worker
58*e5436536SAndroid Build Coastguard Worker constexpr AUDIO_OBJECT_TYPE kAudioObjectTypes[] = {AOT_NONE, AOT_NULL_OBJECT,
59*e5436536SAndroid Build Coastguard Worker AOT_AAC_MAIN, AOT_AAC_LC,
60*e5436536SAndroid Build Coastguard Worker AOT_AAC_SSR, AOT_AAC_LTP,
61*e5436536SAndroid Build Coastguard Worker AOT_SBR, AOT_AAC_SCAL,
62*e5436536SAndroid Build Coastguard Worker AOT_TWIN_VQ, AOT_CELP,
63*e5436536SAndroid Build Coastguard Worker AOT_HVXC, AOT_RSVD_10,
64*e5436536SAndroid Build Coastguard Worker AOT_RSVD_11, AOT_TTSI,
65*e5436536SAndroid Build Coastguard Worker AOT_MAIN_SYNTH, AOT_WAV_TAB_SYNTH,
66*e5436536SAndroid Build Coastguard Worker AOT_GEN_MIDI, AOT_ALG_SYNTH_AUD_FX,
67*e5436536SAndroid Build Coastguard Worker AOT_ER_AAC_LC, AOT_RSVD_18,
68*e5436536SAndroid Build Coastguard Worker AOT_ER_AAC_LTP, AOT_ER_AAC_SCAL,
69*e5436536SAndroid Build Coastguard Worker AOT_ER_TWIN_VQ, AOT_ER_BSAC,
70*e5436536SAndroid Build Coastguard Worker AOT_ER_AAC_LD, AOT_ER_CELP,
71*e5436536SAndroid Build Coastguard Worker AOT_ER_HVXC, AOT_ER_HILN,
72*e5436536SAndroid Build Coastguard Worker AOT_ER_PARA, AOT_RSVD_28,
73*e5436536SAndroid Build Coastguard Worker AOT_PS, AOT_MPEGS,
74*e5436536SAndroid Build Coastguard Worker AOT_ESCAPE, AOT_MP3ONMP4_L1,
75*e5436536SAndroid Build Coastguard Worker AOT_MP3ONMP4_L2, AOT_MP3ONMP4_L3,
76*e5436536SAndroid Build Coastguard Worker AOT_RSVD_35, AOT_RSVD_36,
77*e5436536SAndroid Build Coastguard Worker AOT_AAC_SLS, AOT_SLS,
78*e5436536SAndroid Build Coastguard Worker AOT_ER_AAC_ELD, AOT_USAC,
79*e5436536SAndroid Build Coastguard Worker AOT_SAOC, AOT_LD_MPEGS,
80*e5436536SAndroid Build Coastguard Worker AOT_MP2_AAC_LC, AOT_MP2_SBR,
81*e5436536SAndroid Build Coastguard Worker AOT_DRM_AAC, AOT_DRM_SBR,
82*e5436536SAndroid Build Coastguard Worker AOT_DRM_MPEG_PS, AOT_DRM_SURROUND,
83*e5436536SAndroid Build Coastguard Worker AOT_DRM_USAC};
84*e5436536SAndroid Build Coastguard Worker
85*e5436536SAndroid Build Coastguard Worker constexpr size_t kAudioObjectTypesSize = size(kAudioObjectTypes);
86*e5436536SAndroid Build Coastguard Worker
87*e5436536SAndroid Build Coastguard Worker constexpr int32_t kSbrRatios[] = {-1, 0, 1, 2};
88*e5436536SAndroid Build Coastguard Worker constexpr size_t kSbrRatiosSize = size(kSbrRatios);
89*e5436536SAndroid Build Coastguard Worker
90*e5436536SAndroid Build Coastguard Worker constexpr int32_t kBitRateModes[] = {
91*e5436536SAndroid Build Coastguard Worker AACENC_BR_MODE_INVALID, AACENC_BR_MODE_CBR, AACENC_BR_MODE_VBR_1,
92*e5436536SAndroid Build Coastguard Worker AACENC_BR_MODE_VBR_2, AACENC_BR_MODE_VBR_3, AACENC_BR_MODE_VBR_4,
93*e5436536SAndroid Build Coastguard Worker AACENC_BR_MODE_VBR_5, AACENC_BR_MODE_FF, AACENC_BR_MODE_SFR};
94*e5436536SAndroid Build Coastguard Worker constexpr size_t kBitRateModesSize = size(kBitRateModes);
95*e5436536SAndroid Build Coastguard Worker
96*e5436536SAndroid Build Coastguard Worker constexpr int32_t kGranuleLengths[] = {120, 128, 240, 256, 480, 512, 1024};
97*e5436536SAndroid Build Coastguard Worker constexpr size_t kGranuleLengthsSize = size(kGranuleLengths);
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker constexpr int32_t kChannelOrder[] = {CH_ORDER_MPEG, CH_ORDER_WAV};
100*e5436536SAndroid Build Coastguard Worker constexpr size_t kChannelOrderSize = size(kChannelOrder);
101*e5436536SAndroid Build Coastguard Worker
102*e5436536SAndroid Build Coastguard Worker constexpr int32_t kSignalingModes[] = {-1, 0, 1, 2, 3};
103*e5436536SAndroid Build Coastguard Worker constexpr size_t kSignalingModesSize = size(kSignalingModes);
104*e5436536SAndroid Build Coastguard Worker
105*e5436536SAndroid Build Coastguard Worker constexpr int32_t kAudioMuxVer[] = {-1, 0, 1, 2};
106*e5436536SAndroid Build Coastguard Worker constexpr size_t kAudioMuxVerSize = size(kAudioMuxVer);
107*e5436536SAndroid Build Coastguard Worker
108*e5436536SAndroid Build Coastguard Worker constexpr int32_t kSbrModes[] = {-1, 0, 1, 2};
109*e5436536SAndroid Build Coastguard Worker constexpr size_t kSbrModesSize = size(kSbrModes);
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker constexpr AACENC_METADATA_DRC_PROFILE kMetaDataDrcProfiles[] = {
112*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_NONE, AACENC_METADATA_DRC_FILMSTANDARD,
113*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_FILMLIGHT, AACENC_METADATA_DRC_MUSICSTANDARD,
114*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_MUSICLIGHT, AACENC_METADATA_DRC_SPEECH,
115*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_NOT_PRESENT};
116*e5436536SAndroid Build Coastguard Worker constexpr size_t kMetaDataDrcProfilesSize = size(kMetaDataDrcProfiles);
117*e5436536SAndroid Build Coastguard Worker
118*e5436536SAndroid Build Coastguard Worker enum {
119*e5436536SAndroid Build Coastguard Worker IDX_SBR_MODE = 0,
120*e5436536SAndroid Build Coastguard Worker IDX_AAC_AOT,
121*e5436536SAndroid Build Coastguard Worker IDX_SAMPLE_RATE,
122*e5436536SAndroid Build Coastguard Worker IDX_BIT_RATE_1,
123*e5436536SAndroid Build Coastguard Worker IDX_BIT_RATE_2,
124*e5436536SAndroid Build Coastguard Worker IDX_BIT_RATE_3,
125*e5436536SAndroid Build Coastguard Worker IDX_CHANNEL,
126*e5436536SAndroid Build Coastguard Worker IDX_IDENTIFIER,
127*e5436536SAndroid Build Coastguard Worker IDX_SBR_RATIO,
128*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DRC_PROFILE,
129*e5436536SAndroid Build Coastguard Worker IDX_METADATA_COMP_PROFILE,
130*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DRC_TARGET_REF_LEVEL,
131*e5436536SAndroid Build Coastguard Worker IDX_METADATA_COMP_TARGET_REF_LEVEL,
132*e5436536SAndroid Build Coastguard Worker IDX_METADATA_PROG_LEVEL_PRESENT,
133*e5436536SAndroid Build Coastguard Worker IDX_METADATA_PROG_LEVEL,
134*e5436536SAndroid Build Coastguard Worker IDX_METADATA_PCE_MIXDOWN_IDX_PRESENT,
135*e5436536SAndroid Build Coastguard Worker IDX_METADATA_ETSI_DMXLVL_PRESENT,
136*e5436536SAndroid Build Coastguard Worker IDX_METADATA_CENTER_MIX_LEVEL,
137*e5436536SAndroid Build Coastguard Worker IDX_METADATA_SURROUND_MIX_LEVEL,
138*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DOLBY_SURROUND_MODE,
139*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DRC_PRESENTATION_MODE,
140*e5436536SAndroid Build Coastguard Worker IDX_METADATA_EXT_ANC_DATA_ENABLE,
141*e5436536SAndroid Build Coastguard Worker IDX_METADATA_EXT_DOWNMIX_LEVEL_ENABLE,
142*e5436536SAndroid Build Coastguard Worker IDX_METADATA_EXT_DOWNMIX_LEVEL_A,
143*e5436536SAndroid Build Coastguard Worker IDX_METADATA_EXT_DOWNMIX_LEVEL_B,
144*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DMX_GAIN_ENABLE,
145*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DMX_GAIN_5,
146*e5436536SAndroid Build Coastguard Worker IDX_METADATA_DMX_GAIN_2,
147*e5436536SAndroid Build Coastguard Worker IDX_METADATA_LFE_DMX_ENABLE,
148*e5436536SAndroid Build Coastguard Worker IDX_METADATA_LFE_DMX_LEVEL,
149*e5436536SAndroid Build Coastguard Worker IDX_IN_BUFFER_INDEX_1,
150*e5436536SAndroid Build Coastguard Worker IDX_IN_BUFFER_INDEX_2,
151*e5436536SAndroid Build Coastguard Worker IDX_IN_BUFFER_INDEX_3,
152*e5436536SAndroid Build Coastguard Worker IDX_BIT_RATE_MODE,
153*e5436536SAndroid Build Coastguard Worker IDX_GRANULE_LENGTH,
154*e5436536SAndroid Build Coastguard Worker IDX_CHANNELORDER,
155*e5436536SAndroid Build Coastguard Worker IDX_AFTERBURNER,
156*e5436536SAndroid Build Coastguard Worker IDX_BANDWIDTH,
157*e5436536SAndroid Build Coastguard Worker IDX_PEAK_BITRATE,
158*e5436536SAndroid Build Coastguard Worker IDX_HEADER_PERIOD,
159*e5436536SAndroid Build Coastguard Worker IDX_SIGNALING_MODE,
160*e5436536SAndroid Build Coastguard Worker IDX_TPSUBFRAMES,
161*e5436536SAndroid Build Coastguard Worker IDX_AUDIOMUXVER,
162*e5436536SAndroid Build Coastguard Worker IDX_PROTECTION,
163*e5436536SAndroid Build Coastguard Worker IDX_ANCILLARY_BITRATE,
164*e5436536SAndroid Build Coastguard Worker IDX_METADATA_MODE,
165*e5436536SAndroid Build Coastguard Worker IDX_LAST
166*e5436536SAndroid Build Coastguard Worker };
167*e5436536SAndroid Build Coastguard Worker
168*e5436536SAndroid Build Coastguard Worker template <typename type1, typename type2, typename type3>
generateNumberInRangeFromData(type1 data,type2 min,type3 max)169*e5436536SAndroid Build Coastguard Worker auto generateNumberInRangeFromData(type1 data, type2 min, type3 max) -> decltype(max) {
170*e5436536SAndroid Build Coastguard Worker return (data % (1 + max - min)) + min;
171*e5436536SAndroid Build Coastguard Worker }
172*e5436536SAndroid Build Coastguard Worker
173*e5436536SAndroid Build Coastguard Worker class Codec {
174*e5436536SAndroid Build Coastguard Worker public:
~Codec()175*e5436536SAndroid Build Coastguard Worker ~Codec() { deInitEncoder(); }
176*e5436536SAndroid Build Coastguard Worker bool initEncoder(uint8_t **dataPtr, size_t *sizePtr);
177*e5436536SAndroid Build Coastguard Worker void encodeFrames(const uint8_t *data, size_t size);
178*e5436536SAndroid Build Coastguard Worker void deInitEncoder();
179*e5436536SAndroid Build Coastguard Worker
180*e5436536SAndroid Build Coastguard Worker private:
181*e5436536SAndroid Build Coastguard Worker template <typename type1, typename type2, typename type3>
182*e5436536SAndroid Build Coastguard Worker void setAACParam(type1 data, const AACENC_PARAM aacParam, type2 min, type2 max,
183*e5436536SAndroid Build Coastguard Worker const type3 *array = nullptr);
184*e5436536SAndroid Build Coastguard Worker void setupMetaData(uint8_t *data);
185*e5436536SAndroid Build Coastguard Worker
186*e5436536SAndroid Build Coastguard Worker HANDLE_AACENCODER mEncoder = nullptr;
187*e5436536SAndroid Build Coastguard Worker AACENC_MetaData mMetaData = {};
188*e5436536SAndroid Build Coastguard Worker uint32_t mInBufferIdx_1 = 0;
189*e5436536SAndroid Build Coastguard Worker uint32_t mInBufferIdx_2 = 0;
190*e5436536SAndroid Build Coastguard Worker uint32_t mInBufferIdx_3 = 0;
191*e5436536SAndroid Build Coastguard Worker };
192*e5436536SAndroid Build Coastguard Worker
setupMetaData(uint8_t * data)193*e5436536SAndroid Build Coastguard Worker void Codec::setupMetaData(uint8_t *data) {
194*e5436536SAndroid Build Coastguard Worker uint32_t drcProfileIndex = generateNumberInRangeFromData(data[IDX_METADATA_DRC_PROFILE], 0,
195*e5436536SAndroid Build Coastguard Worker kMetaDataDrcProfilesSize - 1);
196*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_PROFILE drcProfile = kMetaDataDrcProfiles[drcProfileIndex];
197*e5436536SAndroid Build Coastguard Worker mMetaData.drc_profile = drcProfile;
198*e5436536SAndroid Build Coastguard Worker
199*e5436536SAndroid Build Coastguard Worker uint32_t compProfileIndex = generateNumberInRangeFromData(data[IDX_METADATA_COMP_PROFILE], 0,
200*e5436536SAndroid Build Coastguard Worker kMetaDataDrcProfilesSize - 1);
201*e5436536SAndroid Build Coastguard Worker AACENC_METADATA_DRC_PROFILE compProfile = kMetaDataDrcProfiles[compProfileIndex];
202*e5436536SAndroid Build Coastguard Worker mMetaData.comp_profile = compProfile;
203*e5436536SAndroid Build Coastguard Worker
204*e5436536SAndroid Build Coastguard Worker INT drcTargetRefLevel =
205*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_DRC_TARGET_REF_LEVEL], 0, UINT8_MAX);
206*e5436536SAndroid Build Coastguard Worker mMetaData.drc_TargetRefLevel = drcTargetRefLevel;
207*e5436536SAndroid Build Coastguard Worker
208*e5436536SAndroid Build Coastguard Worker INT compTargetRefLevel =
209*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_COMP_TARGET_REF_LEVEL], 0, UINT8_MAX);
210*e5436536SAndroid Build Coastguard Worker mMetaData.comp_TargetRefLevel = compTargetRefLevel;
211*e5436536SAndroid Build Coastguard Worker
212*e5436536SAndroid Build Coastguard Worker INT isProgRefLevelPresent =
213*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_PROG_LEVEL_PRESENT], 0, 1);
214*e5436536SAndroid Build Coastguard Worker mMetaData.prog_ref_level_present = isProgRefLevelPresent;
215*e5436536SAndroid Build Coastguard Worker
216*e5436536SAndroid Build Coastguard Worker INT progRefLevel = generateNumberInRangeFromData(data[IDX_METADATA_PROG_LEVEL], 0, UINT8_MAX);
217*e5436536SAndroid Build Coastguard Worker mMetaData.prog_ref_level = progRefLevel;
218*e5436536SAndroid Build Coastguard Worker
219*e5436536SAndroid Build Coastguard Worker UCHAR isPCEMixdownIdxPresent =
220*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_PCE_MIXDOWN_IDX_PRESENT], 0, 1);
221*e5436536SAndroid Build Coastguard Worker mMetaData.PCE_mixdown_idx_present = isPCEMixdownIdxPresent;
222*e5436536SAndroid Build Coastguard Worker
223*e5436536SAndroid Build Coastguard Worker UCHAR isETSIDmxLvlPresent =
224*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_ETSI_DMXLVL_PRESENT], 0, 1);
225*e5436536SAndroid Build Coastguard Worker mMetaData.ETSI_DmxLvl_present = isETSIDmxLvlPresent;
226*e5436536SAndroid Build Coastguard Worker
227*e5436536SAndroid Build Coastguard Worker SCHAR centerMixLevel = generateNumberInRangeFromData(data[IDX_METADATA_CENTER_MIX_LEVEL], 0, 7);
228*e5436536SAndroid Build Coastguard Worker mMetaData.centerMixLevel = centerMixLevel;
229*e5436536SAndroid Build Coastguard Worker
230*e5436536SAndroid Build Coastguard Worker SCHAR surroundMixLevel =
231*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_SURROUND_MIX_LEVEL], 0, 7);
232*e5436536SAndroid Build Coastguard Worker mMetaData.surroundMixLevel = surroundMixLevel;
233*e5436536SAndroid Build Coastguard Worker
234*e5436536SAndroid Build Coastguard Worker UCHAR dolbySurroundMode =
235*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_DOLBY_SURROUND_MODE], 0, 2);
236*e5436536SAndroid Build Coastguard Worker mMetaData.dolbySurroundMode = dolbySurroundMode;
237*e5436536SAndroid Build Coastguard Worker
238*e5436536SAndroid Build Coastguard Worker UCHAR drcPresentationMode =
239*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_DRC_PRESENTATION_MODE], 0, 2);
240*e5436536SAndroid Build Coastguard Worker mMetaData.drcPresentationMode = drcPresentationMode;
241*e5436536SAndroid Build Coastguard Worker
242*e5436536SAndroid Build Coastguard Worker UCHAR extAncDataEnable =
243*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_EXT_ANC_DATA_ENABLE], 0, 1);
244*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.extAncDataEnable = extAncDataEnable;
245*e5436536SAndroid Build Coastguard Worker
246*e5436536SAndroid Build Coastguard Worker UCHAR extDownmixLevelEnable =
247*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_ENABLE], 0, 1);
248*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.extDownmixLevelEnable = extDownmixLevelEnable;
249*e5436536SAndroid Build Coastguard Worker
250*e5436536SAndroid Build Coastguard Worker UCHAR extDownmixLevel_A =
251*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_A], 0, 7);
252*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.extDownmixLevel_A = extDownmixLevel_A;
253*e5436536SAndroid Build Coastguard Worker
254*e5436536SAndroid Build Coastguard Worker UCHAR extDownmixLevel_B =
255*e5436536SAndroid Build Coastguard Worker generateNumberInRangeFromData(data[IDX_METADATA_EXT_DOWNMIX_LEVEL_B], 0, 7);
256*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.extDownmixLevel_B = extDownmixLevel_B;
257*e5436536SAndroid Build Coastguard Worker
258*e5436536SAndroid Build Coastguard Worker UCHAR dmxGainEnable = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_ENABLE], 0, 1);
259*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.dmxGainEnable = dmxGainEnable;
260*e5436536SAndroid Build Coastguard Worker
261*e5436536SAndroid Build Coastguard Worker INT dmxGain5 = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_5], 0, UINT8_MAX);
262*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.dmxGain5 = dmxGain5;
263*e5436536SAndroid Build Coastguard Worker
264*e5436536SAndroid Build Coastguard Worker INT dmxGain2 = generateNumberInRangeFromData(data[IDX_METADATA_DMX_GAIN_2], 0, UINT8_MAX);
265*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.dmxGain2 = dmxGain2;
266*e5436536SAndroid Build Coastguard Worker
267*e5436536SAndroid Build Coastguard Worker UCHAR lfeDmxEnable = generateNumberInRangeFromData(data[IDX_METADATA_LFE_DMX_ENABLE], 0, 1);
268*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.lfeDmxEnable = lfeDmxEnable;
269*e5436536SAndroid Build Coastguard Worker
270*e5436536SAndroid Build Coastguard Worker UCHAR lfeDmxLevel = generateNumberInRangeFromData(data[IDX_METADATA_LFE_DMX_LEVEL], 0, 15);
271*e5436536SAndroid Build Coastguard Worker mMetaData.ExtMetaData.lfeDmxLevel = lfeDmxLevel;
272*e5436536SAndroid Build Coastguard Worker }
273*e5436536SAndroid Build Coastguard Worker
274*e5436536SAndroid Build Coastguard Worker template <typename type1, typename type2, typename type3>
setAACParam(type1 data,const AACENC_PARAM aacParam,type2 min,type2 max,const type3 * array)275*e5436536SAndroid Build Coastguard Worker void Codec::setAACParam(type1 data, const AACENC_PARAM aacParam, type2 min, type2 max,
276*e5436536SAndroid Build Coastguard Worker const type3 *array) {
277*e5436536SAndroid Build Coastguard Worker auto value = 0;
278*e5436536SAndroid Build Coastguard Worker if (array) {
279*e5436536SAndroid Build Coastguard Worker uint32_t index = generateNumberInRangeFromData(data, min, max);
280*e5436536SAndroid Build Coastguard Worker value = array[index];
281*e5436536SAndroid Build Coastguard Worker } else {
282*e5436536SAndroid Build Coastguard Worker value = generateNumberInRangeFromData(data, min, max);
283*e5436536SAndroid Build Coastguard Worker }
284*e5436536SAndroid Build Coastguard Worker aacEncoder_SetParam(mEncoder, aacParam, value);
285*e5436536SAndroid Build Coastguard Worker (void)aacEncoder_GetParam(mEncoder, aacParam);
286*e5436536SAndroid Build Coastguard Worker }
287*e5436536SAndroid Build Coastguard Worker
initEncoder(uint8_t ** dataPtr,size_t * sizePtr)288*e5436536SAndroid Build Coastguard Worker bool Codec::initEncoder(uint8_t **dataPtr, size_t *sizePtr) {
289*e5436536SAndroid Build Coastguard Worker uint8_t *data = *dataPtr;
290*e5436536SAndroid Build Coastguard Worker
291*e5436536SAndroid Build Coastguard Worker if (AACENC_OK != aacEncOpen(&mEncoder, 0, 0)) {
292*e5436536SAndroid Build Coastguard Worker return false;
293*e5436536SAndroid Build Coastguard Worker }
294*e5436536SAndroid Build Coastguard Worker
295*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_SBR_MODE], AACENC_SBR_MODE, 0, kSbrModesSize - 1,
296*e5436536SAndroid Build Coastguard Worker kSbrModes);
297*e5436536SAndroid Build Coastguard Worker
298*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_SBR_RATIO], AACENC_SBR_RATIO, 0,
299*e5436536SAndroid Build Coastguard Worker kSbrRatiosSize - 1, kSbrRatios);
300*e5436536SAndroid Build Coastguard Worker
301*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, AUDIO_OBJECT_TYPE>(data[IDX_AAC_AOT], AACENC_AOT, 0,
302*e5436536SAndroid Build Coastguard Worker kAudioObjectTypesSize - 1, kAudioObjectTypes);
303*e5436536SAndroid Build Coastguard Worker
304*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_SAMPLE_RATE], AACENC_SAMPLERATE, 0,
305*e5436536SAndroid Build Coastguard Worker kSampleRatesSize - 1, kSampleRates);
306*e5436536SAndroid Build Coastguard Worker
307*e5436536SAndroid Build Coastguard Worker uint32_t tempValue =
308*e5436536SAndroid Build Coastguard Worker (data[IDX_BIT_RATE_1] << 16) | (data[IDX_BIT_RATE_2] << 8) | data[IDX_BIT_RATE_3];
309*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(tempValue, AACENC_BITRATE, kMinBitRate, kMaxBitRate);
310*e5436536SAndroid Build Coastguard Worker
311*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, CHANNEL_MODE>(data[IDX_CHANNEL], AACENC_CHANNELMODE, 0,
312*e5436536SAndroid Build Coastguard Worker kChannelModesSize - 1, kChannelModes);
313*e5436536SAndroid Build Coastguard Worker
314*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, TRANSPORT_TYPE>(data[IDX_IDENTIFIER], AACENC_TRANSMUX, 0,
315*e5436536SAndroid Build Coastguard Worker kIdentifiersSize - 1, kIdentifiers);
316*e5436536SAndroid Build Coastguard Worker
317*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_BIT_RATE_MODE], AACENC_BITRATEMODE, 0,
318*e5436536SAndroid Build Coastguard Worker kBitRateModesSize - 1, kBitRateModes);
319*e5436536SAndroid Build Coastguard Worker
320*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_GRANULE_LENGTH], AACENC_GRANULE_LENGTH, 0,
321*e5436536SAndroid Build Coastguard Worker kGranuleLengthsSize - 1, kGranuleLengths);
322*e5436536SAndroid Build Coastguard Worker
323*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_CHANNELORDER], AACENC_CHANNELORDER, 0,
324*e5436536SAndroid Build Coastguard Worker kChannelOrderSize - 1, kChannelOrder);
325*e5436536SAndroid Build Coastguard Worker
326*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, int32_t, int32_t>(data[IDX_AFTERBURNER], AACENC_AFTERBURNER, 0, 1);
327*e5436536SAndroid Build Coastguard Worker
328*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, int32_t, int32_t>(data[IDX_BANDWIDTH], AACENC_BANDWIDTH, 0, 1);
329*e5436536SAndroid Build Coastguard Worker
330*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_PEAK_BITRATE], AACENC_PEAK_BITRATE,
331*e5436536SAndroid Build Coastguard Worker kMinBitRate, kMinBitRate);
332*e5436536SAndroid Build Coastguard Worker
333*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_HEADER_PERIOD], AACENC_HEADER_PERIOD, 0,
334*e5436536SAndroid Build Coastguard Worker UINT8_MAX);
335*e5436536SAndroid Build Coastguard Worker
336*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_SIGNALING_MODE], AACENC_SIGNALING_MODE, 0,
337*e5436536SAndroid Build Coastguard Worker kSignalingModesSize - 1, kSignalingModes);
338*e5436536SAndroid Build Coastguard Worker
339*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_TPSUBFRAMES], AACENC_TPSUBFRAMES, 0,
340*e5436536SAndroid Build Coastguard Worker UINT8_MAX);
341*e5436536SAndroid Build Coastguard Worker
342*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, size_t, int32_t>(data[IDX_AUDIOMUXVER], AACENC_AUDIOMUXVER, 0,
343*e5436536SAndroid Build Coastguard Worker kAudioMuxVerSize - 1, kAudioMuxVer);
344*e5436536SAndroid Build Coastguard Worker
345*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_PROTECTION], AACENC_PROTECTION, 0, 1);
346*e5436536SAndroid Build Coastguard Worker
347*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_ANCILLARY_BITRATE], AACENC_ANCILLARY_BITRATE,
348*e5436536SAndroid Build Coastguard Worker 0, kMaxBitRate);
349*e5436536SAndroid Build Coastguard Worker
350*e5436536SAndroid Build Coastguard Worker setAACParam<uint8_t, uint32_t, uint32_t>(data[IDX_METADATA_MODE], AACENC_METADATA_MODE, 0, 3);
351*e5436536SAndroid Build Coastguard Worker
352*e5436536SAndroid Build Coastguard Worker AACENC_InfoStruct encInfo;
353*e5436536SAndroid Build Coastguard Worker aacEncInfo(mEncoder, &encInfo);
354*e5436536SAndroid Build Coastguard Worker
355*e5436536SAndroid Build Coastguard Worker mInBufferIdx_1 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_1], 0, kMaxBuffers - 1);
356*e5436536SAndroid Build Coastguard Worker mInBufferIdx_2 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_2], 0, kMaxBuffers - 1);
357*e5436536SAndroid Build Coastguard Worker mInBufferIdx_3 = generateNumberInRangeFromData(data[IDX_IN_BUFFER_INDEX_3], 0, kMaxBuffers - 1);
358*e5436536SAndroid Build Coastguard Worker
359*e5436536SAndroid Build Coastguard Worker setupMetaData(data);
360*e5436536SAndroid Build Coastguard Worker
361*e5436536SAndroid Build Coastguard Worker // Not re-using the data which was used for configuration for encoding
362*e5436536SAndroid Build Coastguard Worker *dataPtr += IDX_LAST;
363*e5436536SAndroid Build Coastguard Worker *sizePtr -= IDX_LAST;
364*e5436536SAndroid Build Coastguard Worker
365*e5436536SAndroid Build Coastguard Worker return true;
366*e5436536SAndroid Build Coastguard Worker }
367*e5436536SAndroid Build Coastguard Worker
deleteBuffers(uint8_t ** buffers,size_t size)368*e5436536SAndroid Build Coastguard Worker static void deleteBuffers(uint8_t **buffers, size_t size) {
369*e5436536SAndroid Build Coastguard Worker for (size_t n = 0; n < size; ++n) {
370*e5436536SAndroid Build Coastguard Worker delete[] buffers[n];
371*e5436536SAndroid Build Coastguard Worker }
372*e5436536SAndroid Build Coastguard Worker delete[] buffers;
373*e5436536SAndroid Build Coastguard Worker }
374*e5436536SAndroid Build Coastguard Worker
encodeFrames(const uint8_t * data,size_t size)375*e5436536SAndroid Build Coastguard Worker void Codec::encodeFrames(const uint8_t *data, size_t size) {
376*e5436536SAndroid Build Coastguard Worker uint8_t *audioData = (uint8_t *)data;
377*e5436536SAndroid Build Coastguard Worker uint8_t *ancData = (uint8_t *)data;
378*e5436536SAndroid Build Coastguard Worker size_t audioSize = size;
379*e5436536SAndroid Build Coastguard Worker size_t ancSize = size;
380*e5436536SAndroid Build Coastguard Worker
381*e5436536SAndroid Build Coastguard Worker while ((audioSize > 0) && (ancSize > 0)) {
382*e5436536SAndroid Build Coastguard Worker AACENC_InArgs inargs;
383*e5436536SAndroid Build Coastguard Worker memset(&inargs, 0, sizeof(inargs));
384*e5436536SAndroid Build Coastguard Worker inargs.numInSamples = audioSize / sizeof(int16_t);
385*e5436536SAndroid Build Coastguard Worker inargs.numAncBytes = ancSize;
386*e5436536SAndroid Build Coastguard Worker
387*e5436536SAndroid Build Coastguard Worker void *buffers[] = {(void *)audioData, (void *)ancData, &mMetaData};
388*e5436536SAndroid Build Coastguard Worker INT bufferIds[] = {IN_AUDIO_DATA, IN_ANCILLRY_DATA, IN_METADATA_SETUP};
389*e5436536SAndroid Build Coastguard Worker INT bufferSizes[] = {static_cast<INT>(audioSize), static_cast<INT>(ancSize),
390*e5436536SAndroid Build Coastguard Worker static_cast<INT>(sizeof(mMetaData))};
391*e5436536SAndroid Build Coastguard Worker INT bufferElSizes[] = {sizeof(int16_t), sizeof(UCHAR), sizeof(AACENC_MetaData)};
392*e5436536SAndroid Build Coastguard Worker
393*e5436536SAndroid Build Coastguard Worker void *inBuffer[kMaxBuffers] = {};
394*e5436536SAndroid Build Coastguard Worker INT inBufferIds[kMaxBuffers] = {};
395*e5436536SAndroid Build Coastguard Worker INT inBufferSize[kMaxBuffers] = {};
396*e5436536SAndroid Build Coastguard Worker INT inBufferElSize[kMaxBuffers] = {};
397*e5436536SAndroid Build Coastguard Worker for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
398*e5436536SAndroid Build Coastguard Worker uint32_t Idxs[] = {mInBufferIdx_1, mInBufferIdx_2, mInBufferIdx_3};
399*e5436536SAndroid Build Coastguard Worker inBuffer[buffer] = buffers[Idxs[buffer]];
400*e5436536SAndroid Build Coastguard Worker inBufferIds[buffer] = bufferIds[Idxs[buffer]];
401*e5436536SAndroid Build Coastguard Worker inBufferSize[buffer] = bufferSizes[Idxs[buffer]];
402*e5436536SAndroid Build Coastguard Worker inBufferElSize[buffer] = bufferElSizes[Idxs[buffer]];
403*e5436536SAndroid Build Coastguard Worker }
404*e5436536SAndroid Build Coastguard Worker
405*e5436536SAndroid Build Coastguard Worker AACENC_BufDesc inBufDesc;
406*e5436536SAndroid Build Coastguard Worker inBufDesc.numBufs = kMaxBuffers;
407*e5436536SAndroid Build Coastguard Worker inBufDesc.bufs = (void **)&inBuffer;
408*e5436536SAndroid Build Coastguard Worker inBufDesc.bufferIdentifiers = inBufferIds;
409*e5436536SAndroid Build Coastguard Worker inBufDesc.bufSizes = inBufferSize;
410*e5436536SAndroid Build Coastguard Worker inBufDesc.bufElSizes = inBufferElSize;
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker uint8_t **outPtrRef = new uint8_t *[kMaxBuffers];
413*e5436536SAndroid Build Coastguard Worker for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
414*e5436536SAndroid Build Coastguard Worker outPtrRef[buffer] = new uint8_t[kMaxOutputBufferSize];
415*e5436536SAndroid Build Coastguard Worker }
416*e5436536SAndroid Build Coastguard Worker
417*e5436536SAndroid Build Coastguard Worker void *outBuffer[kMaxBuffers];
418*e5436536SAndroid Build Coastguard Worker INT outBufferIds[kMaxBuffers];
419*e5436536SAndroid Build Coastguard Worker INT outBufferSize[kMaxBuffers];
420*e5436536SAndroid Build Coastguard Worker INT outBufferElSize[kMaxBuffers];
421*e5436536SAndroid Build Coastguard Worker
422*e5436536SAndroid Build Coastguard Worker for (int32_t buffer = 0; buffer < kMaxBuffers; ++buffer) {
423*e5436536SAndroid Build Coastguard Worker outBuffer[buffer] = outPtrRef[buffer];
424*e5436536SAndroid Build Coastguard Worker outBufferIds[buffer] = OUT_BITSTREAM_DATA;
425*e5436536SAndroid Build Coastguard Worker outBufferSize[buffer] = (INT)kMaxOutputBufferSize;
426*e5436536SAndroid Build Coastguard Worker outBufferElSize[buffer] = sizeof(UCHAR);
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker
429*e5436536SAndroid Build Coastguard Worker AACENC_BufDesc outBufDesc;
430*e5436536SAndroid Build Coastguard Worker outBufDesc.numBufs = kMaxBuffers;
431*e5436536SAndroid Build Coastguard Worker outBufDesc.bufs = (void **)&outBuffer;
432*e5436536SAndroid Build Coastguard Worker outBufDesc.bufferIdentifiers = outBufferIds;
433*e5436536SAndroid Build Coastguard Worker outBufDesc.bufSizes = outBufferSize;
434*e5436536SAndroid Build Coastguard Worker outBufDesc.bufElSizes = outBufferElSize;
435*e5436536SAndroid Build Coastguard Worker
436*e5436536SAndroid Build Coastguard Worker AACENC_OutArgs outargs = {};
437*e5436536SAndroid Build Coastguard Worker aacEncEncode(mEncoder, &inBufDesc, &outBufDesc, &inargs, &outargs);
438*e5436536SAndroid Build Coastguard Worker
439*e5436536SAndroid Build Coastguard Worker if (outargs.numOutBytes == 0) {
440*e5436536SAndroid Build Coastguard Worker if (audioSize > 0) {
441*e5436536SAndroid Build Coastguard Worker ++audioData;
442*e5436536SAndroid Build Coastguard Worker --audioSize;
443*e5436536SAndroid Build Coastguard Worker }
444*e5436536SAndroid Build Coastguard Worker if (ancSize > 0) {
445*e5436536SAndroid Build Coastguard Worker ++ancData;
446*e5436536SAndroid Build Coastguard Worker --ancSize;
447*e5436536SAndroid Build Coastguard Worker }
448*e5436536SAndroid Build Coastguard Worker } else {
449*e5436536SAndroid Build Coastguard Worker size_t audioConsumed = outargs.numInSamples * sizeof(int16_t);
450*e5436536SAndroid Build Coastguard Worker audioData += audioConsumed;
451*e5436536SAndroid Build Coastguard Worker audioSize -= audioConsumed;
452*e5436536SAndroid Build Coastguard Worker
453*e5436536SAndroid Build Coastguard Worker size_t ancConsumed = outargs.numAncBytes;
454*e5436536SAndroid Build Coastguard Worker ancData += ancConsumed;
455*e5436536SAndroid Build Coastguard Worker ancSize -= ancConsumed;
456*e5436536SAndroid Build Coastguard Worker }
457*e5436536SAndroid Build Coastguard Worker deleteBuffers(outPtrRef, kMaxBuffers);
458*e5436536SAndroid Build Coastguard Worker
459*e5436536SAndroid Build Coastguard Worker // break out of loop if only metadata was sent in all the input buffers
460*e5436536SAndroid Build Coastguard Worker // as sending it multiple times in a loop is redundant.
461*e5436536SAndroid Build Coastguard Worker if ((mInBufferIdx_1 == kMaxBuffers - 1) && (mInBufferIdx_2 == kMaxBuffers - 1) &&
462*e5436536SAndroid Build Coastguard Worker (mInBufferIdx_3 == kMaxBuffers - 1)) {
463*e5436536SAndroid Build Coastguard Worker break;
464*e5436536SAndroid Build Coastguard Worker }
465*e5436536SAndroid Build Coastguard Worker }
466*e5436536SAndroid Build Coastguard Worker }
467*e5436536SAndroid Build Coastguard Worker
deInitEncoder()468*e5436536SAndroid Build Coastguard Worker void Codec::deInitEncoder() { aacEncClose(&mEncoder); }
469*e5436536SAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)470*e5436536SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
471*e5436536SAndroid Build Coastguard Worker if (size < IDX_LAST) {
472*e5436536SAndroid Build Coastguard Worker return 0;
473*e5436536SAndroid Build Coastguard Worker }
474*e5436536SAndroid Build Coastguard Worker Codec encoder;
475*e5436536SAndroid Build Coastguard Worker if (encoder.initEncoder(const_cast<uint8_t **>(&data), &size)) {
476*e5436536SAndroid Build Coastguard Worker encoder.encodeFrames(data, size);
477*e5436536SAndroid Build Coastguard Worker }
478*e5436536SAndroid Build Coastguard Worker return 0;
479*e5436536SAndroid Build Coastguard Worker }
480