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