xref: /aosp_15_r20/external/libxaac/fuzzer/xaac_dec_fuzzer.cpp (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *
3  * Copyright (C) 2019 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 <stddef.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <vector>
28 
29 #include "ixheaac_type_def.h"
30 #include "ixheaac_error_standards.h"
31 #include "ixheaacd_error_handler.h"
32 #include "ixheaacd_apicmd_standards.h"
33 #include "ixheaacd_memory_standards.h"
34 #include "ixheaacd_aac_config.h"
35 
36 #include "impd_apicmd_standards.h"
37 #include "impd_drc_config_params.h"
38 
39 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
40 #define DRC_DEFAULT_MOBILE_REF_LEVEL 64
41 /* maximum compression of dynamic range for mobile conf */
42 #define DRC_DEFAULT_MOBILE_DRC_CUT 127
43 /* maximum compression of dynamic range for mobile conf */
44 #define DRC_DEFAULT_MOBILE_DRC_BOOST 127
45 /* switch for heavy compression for mobile conf */
46 #define DRC_DEFAULT_MOBILE_DRC_HEAVY 1
47 /* encoder target level; -1 => the value is unknown, otherwise dB \
48              step value (e.g. 64 for -16 dB) */
49 #define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1)
50 
51 #define MAX_CHANNEL_COUNT 8
52 
53 #define MAX_MEM_ALLOCS 100
54 
55 #define IA_MAX_OUTPUT_PCM_SIZE (3)
56 #define IA_MAX_USAC_CH (2)
57 #define IA_MAX_OUT_SAMPLES_PER_FRAME (4096)
58 
59 #define IA_DRC_DEC_IN_OUT_BUF_SIZE \
60   (IA_MAX_USAC_CH * IA_MAX_OUT_SAMPLES_PER_FRAME * IA_MAX_OUTPUT_PCM_SIZE)
61 
62 class Codec {
63  public:
64   IA_ERRORCODE initDecoder(const uint8_t* data, size_t size, bool isADTS);
65   IA_ERRORCODE initXAACDecoder(bool isADTS);
66   IA_ERRORCODE initXAACDrc(const uint8_t* data, size_t size);
67   IA_ERRORCODE deInitXAACDecoder();
68   IA_ERRORCODE deInitMPEGDDDrc();
69   IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength,
70                                  int32_t* bytesConsumed);
71   IA_ERRORCODE initMPEGDDDrc();
72   int configMPEGDDrc();
73   IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
74                                 int32_t* bytesConsumed, int32_t* outBytes);
75   IA_ERRORCODE getXAACStreamInfo();
76   IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
77                               int32_t drcRefLevel, int32_t drcHeavyCompression,
78                               int32_t drEffectType);
79 
80  private:
81   void* mXheaacCodecHandle;
82   void* mMpegDDrcHandle;
83   uint32_t mInputBufferSize;
84   uint32_t mOutputFrameLength;
85   int8_t* mInputBuffer;
86   int8_t* mOutputBuffer;
87   int32_t mSampFreq;
88   int32_t mNumChannels;
89   int32_t mPcmWdSz;
90   int32_t mChannelMask;
91   bool mIsCodecInitialized;
92   bool mIsCodecConfigFlushRequired;
93   int8_t* mDrcInBuf;
94   int8_t* mDrcOutBuf;
95   int32_t mMpegDDRCPresent;
96   int32_t mDRCFlag;
97 
98   std::vector<void*> mMemoryVec;
99   std::vector<void*> mDrcMemoryVec;
100 };
101 
102 extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd,
103                                          WORD32 i_idx, pVOID pv_value);
104 extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd,
105                                        WORD32 i_idx, pVOID pv_value);
106 extern "C" IA_ERRORCODE ixheaacd_get_config_param(pVOID p_ia_process_api_obj,
107                                                   pWORD32 pi_samp_freq,
108                                                   pWORD32 pi_num_chan,
109                                                   pWORD32 pi_pcm_wd_sz,
110                                                   pWORD32 pi_channel_mask);
111 
initXAACDecoder(bool isADTS)112 IA_ERRORCODE Codec::initXAACDecoder(bool isADTS) {
113   /* First part                                        */
114   /* Error Handler Init                                */
115   /* Get Library Name, Library Version and API Version */
116   /* Initialize API structure + Default config set     */
117   /* Set config params from user                       */
118   /* Initialize memory tables                          */
119   /* Get memory information and allocate memory        */
120 
121   mInputBufferSize = 0;
122   mInputBuffer = nullptr;
123   mOutputBuffer = nullptr;
124   /* Process struct initing end */
125 
126   /* ******************************************************************/
127   /* Initialize API structure and set config params to default        */
128   /* ******************************************************************/
129   /* API size */
130   uint32_t pui_api_size;
131   /* Get the API size */
132   IA_ERRORCODE err_code =
133       ixheaacd_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
134 
135   /* Allocate memory for API */
136   mXheaacCodecHandle = malloc(pui_api_size);
137   if (!mXheaacCodecHandle) {
138     return IA_FATAL_ERROR;
139   }
140   mMemoryVec.push_back(mXheaacCodecHandle);
141 
142   /* Set the config params to default values */
143   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
144                               IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
145 
146   /* Get the API size */
147   err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
148 
149   /* Allocate memory for API */
150   mMpegDDrcHandle = malloc(pui_api_size);
151   if (!mMpegDDrcHandle) {
152     return IA_FATAL_ERROR;
153   }
154   mMemoryVec.push_back(mMpegDDrcHandle);
155 
156   /* Set the config params to default values */
157   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
158                             IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
159 
160   /* ******************************************************************/
161   /* Set config parameters                                            */
162   /* ******************************************************************/
163   uint32_t ui_mp4_flag = isADTS ? 0 : 1;
164   err_code =
165       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
166                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &ui_mp4_flag);
167 
168   /* ******************************************************************/
169   /* Initialize Memory info tables                                    */
170   /* ******************************************************************/
171   uint32_t ui_proc_mem_tabs_size;
172   pVOID pv_alloc_ptr;
173   /* Get memory info tables size */
174   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEMTABS_SIZE,
175                               0, &ui_proc_mem_tabs_size);
176 
177   pv_alloc_ptr = malloc(ui_proc_mem_tabs_size);
178   if (!pv_alloc_ptr) {
179     return IA_FATAL_ERROR;
180   }
181   mMemoryVec.push_back(pv_alloc_ptr);
182 
183   /* Set pointer for process memory tables    */
184   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
185                               pv_alloc_ptr);
186 
187   /* initialize the API, post config, fill memory tables  */
188   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
189                               IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
190 
191   /* ******************************************************************/
192   /* Allocate Memory with info from library                           */
193   /* ******************************************************************/
194   /* There are four different types of memories, that needs to be allocated */
195   /* persistent,scratch,input and output */
196   for (int i = 0; i < 4; i++) {
197     int ui_size = 0, ui_alignment = 0, ui_type = 0;
198 
199     /* Get memory size */
200     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
201                                 IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
202 
203     /* Get memory alignment */
204     err_code =
205         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
206                          i, &ui_alignment);
207 
208     /* Get memory type */
209     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
210                                 IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
211 
212     pv_alloc_ptr = NULL;
213     ui_alignment = (ui_alignment + sizeof(void *) - 1) / sizeof(void *);
214     ui_alignment = ui_alignment * sizeof(void *);
215     if (0 != posix_memalign(&pv_alloc_ptr, ui_alignment, ui_size)) {
216       return IA_FATAL_ERROR;
217     }
218     if (!pv_alloc_ptr) {
219       return IA_FATAL_ERROR;
220     }
221     mMemoryVec.push_back(pv_alloc_ptr);
222 
223     /* Set the buffer pointer */
224     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i,
225                                 pv_alloc_ptr);
226 
227     if (ui_type == IA_MEMTYPE_INPUT) {
228       mInputBuffer = (pWORD8)pv_alloc_ptr;
229       mInputBufferSize = ui_size;
230     }
231     if (ui_type == IA_MEMTYPE_OUTPUT) mOutputBuffer = (pWORD8)pv_alloc_ptr;
232   }
233   /* End first part */
234 
235   return IA_NO_ERROR;
236 }
237 enum {
238   DRC_TARGET_LEVEL_OFFSET = 6,
239   DRC_ATTENUATION_OFFSET,
240   DRC_BOOST_OFFSET,
241   DRC_COMPRESS_OFFSET,
242   DRC_EFFECT_OFFSET
243 };
244 
initXAACDrc(const uint8_t * data,size_t size)245 IA_ERRORCODE Codec::initXAACDrc(const uint8_t* data, size_t size) {
246   IA_ERRORCODE err_code = IA_NO_ERROR;
247   unsigned int ui_drc_val;
248   //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
249   size_t targetLevelOffset =
250       std::min((size_t)DRC_TARGET_LEVEL_OFFSET, size - 1);
251   int32_t targetRefLevel = data[targetLevelOffset];
252 
253   ui_drc_val = (unsigned int)targetRefLevel;
254   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
255                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
256                               &ui_drc_val);
257 
258   /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or
259    * DRC_DEFAULT_MOBILE_REF_LEVEL
260    * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
261   err_code =
262       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
263                        IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
264 
265   size_t attenuationOffset = std::min((size_t)DRC_ATTENUATION_OFFSET, size - 1);
266   int32_t attenuationFactor = data[attenuationOffset];
267 
268   ui_drc_val = (unsigned int)attenuationFactor;
269   err_code =
270       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
271                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &ui_drc_val);
272 
273   //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
274   size_t boostOffset = std::min((size_t)DRC_BOOST_OFFSET, size - 1);
275   int32_t boostFactor = data[boostOffset];
276 
277   ui_drc_val = (unsigned int)boostFactor;
278   err_code =
279       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
280                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &ui_drc_val);
281 
282   //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
283   size_t compressOffset = std::min((size_t)DRC_COMPRESS_OFFSET, size - 1);
284   int32_t compressMode = data[compressOffset];
285   ui_drc_val = (unsigned int)compressMode;
286 
287   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
288                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
289                               &ui_drc_val);
290 
291   // AAC_UNIDRC_SET_EFFECT
292   size_t effectOffset = std::min((size_t)DRC_EFFECT_OFFSET, size - 1);
293   int32_t effectType = data[effectOffset];
294   ui_drc_val = (unsigned int)effectType;
295   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
296                               IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
297 
298   return IA_NO_ERROR;
299 }
300 
deInitXAACDecoder()301 IA_ERRORCODE Codec::deInitXAACDecoder() {
302   /* Error code */
303   IA_ERRORCODE err_code = IA_NO_ERROR;
304 
305   if (mXheaacCodecHandle) {
306     /* Tell that the input is over in this buffer */
307     err_code =
308         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, nullptr);
309   }
310 
311   /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated
312    * memory */
313   for (void* buf : mMemoryVec) {
314     if (buf) free(buf);
315   }
316   mMemoryVec.clear();
317   mXheaacCodecHandle = nullptr;
318 
319   return err_code;
320 }
321 
deInitMPEGDDDrc()322 IA_ERRORCODE Codec::deInitMPEGDDDrc() {
323   for (void* buf : mDrcMemoryVec) {
324     if (buf) free(buf);
325   }
326   mDrcMemoryVec.clear();
327   return IA_NO_ERROR;
328 }
329 
configXAACDecoder(uint8_t * inBuffer,uint32_t inBufferLength,int32_t * bytesConsumed)330 IA_ERRORCODE Codec::configXAACDecoder(uint8_t* inBuffer,
331                                       uint32_t inBufferLength,
332                                       int32_t* bytesConsumed) {
333   if (mInputBufferSize < inBufferLength) {
334     inBufferLength = mInputBufferSize;
335   }
336   /* Copy the buffer passed by Android plugin to codec input buffer */
337   memcpy(mInputBuffer, inBuffer, inBufferLength);
338 
339   /* Set number of bytes to be processed */
340   IA_ERRORCODE err_code = ixheaacd_dec_api(
341       mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
342 
343   if (mIsCodecConfigFlushRequired) {
344     /* If codec is already initialized, then GA header is passed again */
345     /* Need to call the Flush API instead of INIT_PROCESS */
346     mIsCodecInitialized =
347         false; /* Codec needs to be Reinitialized after flush */
348     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
349                                 IA_CMD_TYPE_GA_HDR, nullptr);
350 
351   } else {
352     /* Initialize the process */
353     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
354                                 IA_CMD_TYPE_INIT_PROCESS, nullptr);
355   }
356 
357   uint32_t ui_init_done;
358   /* Checking for end of initialization */
359   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
360                               IA_CMD_TYPE_INIT_DONE_QUERY, &ui_init_done);
361 
362   /* How much buffer is used in input buffers */
363   err_code = ixheaacd_dec_api(
364       mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, bytesConsumed);
365 
366   if (ui_init_done) {
367     err_code = getXAACStreamInfo();
368 
369     mIsCodecInitialized = true;
370 
371     err_code = configMPEGDDrc();
372   }
373 
374   return IA_NO_ERROR;
375 }
initMPEGDDDrc()376 IA_ERRORCODE Codec::initMPEGDDDrc() {
377   IA_ERRORCODE err_code = IA_NO_ERROR;
378 
379   for (int i = 0; i < (WORD32)2; i++) {
380     WORD32 ui_size, ui_alignment, ui_type;
381     pVOID pv_alloc_ptr;
382 
383     /* Get memory size */
384     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i,
385                               &ui_size);
386 
387     /* Get memory alignment */
388     err_code = ia_drc_dec_api(
389         mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
390 
391     /* Get memory type */
392     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i,
393                               &ui_type);
394 
395     pv_alloc_ptr = malloc(ui_size);
396     if (pv_alloc_ptr == nullptr) {
397       return IA_FATAL_ERROR;
398     }
399     mDrcMemoryVec.push_back(pv_alloc_ptr);
400 
401     /* Set the buffer pointer */
402     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i,
403                               pv_alloc_ptr);
404   }
405 
406   mDrcInBuf = (int8_t*)malloc(IA_DRC_DEC_IN_OUT_BUF_SIZE);
407   if (mDrcInBuf == nullptr) {
408     return IA_FATAL_ERROR;
409   }
410   mDrcMemoryVec.push_back(mDrcInBuf);
411 
412   err_code =
413       ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
414 
415   mDrcOutBuf = (int8_t*)malloc(IA_DRC_DEC_IN_OUT_BUF_SIZE);
416   if (mDrcOutBuf == nullptr) {
417     return IA_FATAL_ERROR;
418   }
419   mDrcMemoryVec.push_back(mDrcOutBuf);
420 
421   err_code =
422       ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
423 
424   return IA_NO_ERROR;
425 }
configMPEGDDrc()426 int Codec::configMPEGDDrc() {
427   IA_ERRORCODE err_code = IA_NO_ERROR;
428   int i_effect_type;
429   int i_loud_norm;
430   int i_target_loudness;
431   unsigned int i_sbr_mode;
432   uint32_t ui_proc_mem_tabs_size = 0;
433   pVOID pv_alloc_ptr = NULL;
434 
435   /* Sampling Frequency */
436   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
437                             IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
438 
439   /* Total Number of Channels */
440   err_code =
441       ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
442                      IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
443 
444   /* PCM word size  */
445   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
446                             IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
447 
448   /*Set Effect Type*/
449   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
450                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
451                               &i_effect_type);
452 
453   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
454                             IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
455 
456   /*Set target loudness */
457   err_code = ixheaacd_dec_api(
458       mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
459       IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
460 
461   err_code =
462       ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
463                      IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
464 
465   /*Set loud_norm_flag*/
466   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
467                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
468                               &i_loud_norm);
469 
470   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
471                             IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
472 
473   err_code =
474       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
475                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
476 
477   /* Get memory info tables size */
478   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
479                             &ui_proc_mem_tabs_size);
480 
481   pv_alloc_ptr = malloc(ui_proc_mem_tabs_size);
482   if (pv_alloc_ptr == NULL) {
483     return IA_FATAL_ERROR;
484   }
485   memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
486   mMemoryVec.push_back(pv_alloc_ptr);
487 
488   /* Set pointer for process memory tables */
489   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
490                             pv_alloc_ptr);
491 
492   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
493                             IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
494 
495   /* Free any memory that is allocated for MPEG D Drc so far */
496   deInitMPEGDDDrc();
497 
498   err_code = initMPEGDDDrc();
499   if (err_code != IA_NO_ERROR) {
500     deInitMPEGDDDrc();
501     return err_code;
502   }
503 
504   /* DRC buffers
505       buf[0] - contains extension element pay load loudness related
506       buf[1] - contains extension element pay load*/
507   {
508     VOID* p_array[2][16];
509     WORD32 ii;
510     WORD32 buf_sizes[2][16];
511     WORD32 num_elements;
512     WORD32 num_config_ext;
513     WORD32 bit_str_fmt = 1;
514 
515     WORD32 uo_num_chan;
516 
517     memset(buf_sizes, 0, 32 * sizeof(WORD32));
518 
519     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
520                                 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES,
521                                 &buf_sizes[0][0]);
522 
523     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
524                                 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
525 
526     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
527                               IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
528 
529     err_code =
530         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
531                          IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
532 
533     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
534                                 IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT,
535                                 &num_config_ext);
536 
537     for (ii = 0; ii < num_config_ext; ii++) {
538       /*copy loudness bitstream*/
539       if (buf_sizes[0][ii] > 0) {
540         memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
541 
542         /*Set bitstream_split_format */
543         err_code =
544             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
545                            IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
546 
547         /* Set number of bytes to be processed */
548         err_code =
549             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
550                            &buf_sizes[0][ii]);
551 
552         /* Execute process */
553         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
554                                   IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
555 
556         mDRCFlag = 1;
557       }
558     }
559 
560     for (ii = 0; ii < num_elements; ii++) {
561       /*copy config bitstream*/
562       if (buf_sizes[1][ii] > 0) {
563         memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
564         /* Set number of bytes to be processed */
565 
566         /*Set bitstream_split_format */
567         err_code =
568             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
569                            IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
570 
571         err_code =
572             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
573                            &buf_sizes[1][ii]);
574 
575         /* Execute process */
576         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
577                                   IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
578 
579         mDRCFlag = 1;
580       }
581     }
582 
583     if (mDRCFlag == 1) {
584       mMpegDDRCPresent = 1;
585     } else {
586       mMpegDDRCPresent = 0;
587     }
588 
589     /*Read interface buffer config file bitstream*/
590     if (mMpegDDRCPresent == 1) {
591       WORD32 interface_is_present = 1;
592 
593       if (i_sbr_mode != 0) {
594         if (i_sbr_mode == 1) {
595           mOutputFrameLength = 2048;
596         } else if (i_sbr_mode == 3) {
597           mOutputFrameLength = 4096;
598         } else {
599           mOutputFrameLength = 1024;
600         }
601       } else {
602         mOutputFrameLength = 4096;
603       }
604 
605       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
606                                 IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE,
607                                 (WORD32*)&mOutputFrameLength);
608 
609       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
610                                 IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT,
611                                 &interface_is_present);
612 
613       /* Execute process */
614       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
615                                 IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
616 
617       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
618                                 IA_CMD_TYPE_INIT_PROCESS, nullptr);
619 
620       err_code =
621           ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
622                          IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
623     }
624   }
625 
626   return err_code;
627 }
initDecoder(const uint8_t * data,size_t size,bool isADTS)628 IA_ERRORCODE Codec::initDecoder(const uint8_t* data, size_t size, bool isADTS) {
629   IA_ERRORCODE err_code = IA_NO_ERROR;
630 
631   err_code = initXAACDecoder(isADTS);
632   if (err_code != IA_NO_ERROR) {
633     /* Call deInit to free any allocated memory */
634     deInitXAACDecoder();
635     return IA_FATAL_ERROR;
636   }
637 
638   err_code = initXAACDrc(data, size);
639 
640   return IA_NO_ERROR;
641 }
decodeXAACStream(uint8_t * inBuffer,uint32_t inBufferLength,int32_t * bytesConsumed,int32_t * outBytes)642 IA_ERRORCODE Codec::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
643                                      int32_t* bytesConsumed,
644                                      int32_t* outBytes) {
645   if (mInputBufferSize < inBufferLength) {
646     inBufferLength = mInputBufferSize;
647   }
648   /* If codec is not initialized, call configXAACDecoder decoder again */
649   if (!mIsCodecInitialized) {
650     configXAACDecoder(inBuffer, inBufferLength, bytesConsumed);
651   }
652   /* Copy the buffer passed by Android plugin to codec input buffer */
653   memcpy(mInputBuffer, inBuffer, inBufferLength);
654 
655   /* Set number of bytes to be processed */
656   IA_ERRORCODE err_code = ixheaacd_dec_api(
657       mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
658 
659   /* Execute process */
660   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE,
661                               IA_CMD_TYPE_DO_EXECUTE, nullptr);
662 
663   /* Checking for end of processing */
664   uint32_t ui_exec_done;
665   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE,
666                               IA_CMD_TYPE_DONE_QUERY, &ui_exec_done);
667 
668   if (ui_exec_done != 1) {
669     VOID* p_array;        // ITTIAM:buffer to handle gain payload
670     WORD32 buf_size = 0;  // ITTIAM:gain payload length
671     WORD32 bit_str_fmt = 1;
672     WORD32 gain_stream_flag = 1;
673 
674     err_code =
675         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
676                          IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
677 
678     err_code =
679         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
680                          IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
681 
682     if (buf_size > 0) {
683       /*Set bitstream_split_format */
684       err_code =
685           ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
686                          IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
687 
688       memcpy(mDrcInBuf, p_array, buf_size);
689       /* Set number of bytes to be processed */
690       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS,
691                                 0, &buf_size);
692 
693       err_code =
694           ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
695                          IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
696 
697       /* Execute process */
698       err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
699                                 IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
700 
701       mMpegDDRCPresent = 1;
702     }
703   }
704 
705   /* How much buffer is used in input buffers */
706   err_code = ixheaacd_dec_api(
707       mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, bytesConsumed);
708 
709   /* Get the output bytes */
710   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_OUTPUT_BYTES,
711                               0, outBytes);
712 
713   if (mMpegDDRCPresent == 1) {
714     memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
715     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0,
716                               outBytes);
717 
718     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE,
719                               IA_CMD_TYPE_DO_EXECUTE, nullptr);
720 
721     memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
722   }
723   return IA_NO_ERROR;
724 }
725 
getXAACStreamInfo()726 IA_ERRORCODE Codec::getXAACStreamInfo() {
727   IA_ERRORCODE err_code = IA_NO_ERROR;
728 
729   /* Sampling frequency */
730   err_code =
731       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
732                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
733 
734   /* Total Number of Channels */
735   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
736                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
737                               &mNumChannels);
738 
739   if (mNumChannels > MAX_CHANNEL_COUNT) {
740     return IA_FATAL_ERROR;
741   }
742 
743   /* PCM word size */
744   err_code =
745       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
746                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
747 
748   if ((mPcmWdSz / 8) != 2) {
749     return IA_FATAL_ERROR;
750   }
751 
752   /* channel mask to tell the arrangement of channels in bit stream */
753   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
754                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
755                               &mChannelMask);
756 
757   /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
758   uint32_t ui_channel_mode;
759   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
760                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
761                               &ui_channel_mode);
762 
763   /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
764   uint32_t ui_sbr_mode;
765   err_code =
766       ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
767                        IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &ui_sbr_mode);
768 
769   /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
770   /* For USAC it could be 1024 * 3 , support to query  */
771   /* not yet added in codec                            */
772   mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
773 
774   return IA_NO_ERROR;
775 }
776 
setXAACDRCInfo(int32_t drcCut,int32_t drcBoost,int32_t drcRefLevel,int32_t drcHeavyCompression,int32_t drEffectType)777 IA_ERRORCODE Codec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
778                                    int32_t drcRefLevel,
779                                    int32_t drcHeavyCompression,
780                                    int32_t drEffectType) {
781   IA_ERRORCODE err_code = IA_NO_ERROR;
782 
783   int32_t ui_drc_enable = 1;
784   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
785                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
786                               &ui_drc_enable);
787 
788   if (drcCut != -1) {
789     err_code =
790         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
791                          IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
792   }
793 
794   if (drcBoost != -1) {
795     err_code =
796         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
797                          IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
798   }
799 
800   if (drcRefLevel != -1) {
801     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
802                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
803                                 &drcRefLevel);
804   }
805 
806   if (drcRefLevel != -1) {
807     err_code =
808         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
809                          IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
810   }
811 
812   if (drcHeavyCompression != -1) {
813     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
814                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
815                                 &drcHeavyCompression);
816   }
817 
818   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
819                               IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
820 
821   int32_t i_effect_type, i_target_loudness, i_loud_norm;
822   /*Set Effect Type*/
823   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
824                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
825                               &i_effect_type);
826 
827   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
828                             IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
829 
830   /*Set target loudness */
831   err_code = ixheaacd_dec_api(
832       mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
833       IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
834 
835   err_code =
836       ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
837                      IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
838 
839   /*Set loud_norm_flag*/
840   err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
841                               IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
842                               &i_loud_norm);
843 
844   err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
845                             IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
846 
847   return IA_NO_ERROR;
848 }
849 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)850 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
851   int status;
852   int num_proc_iterations = 0;
853   if (size < 1) return 0;
854   Codec* codec = new Codec();
855   bool isADTS = false;
856   if (size >= 2) {
857     if ((data[0] == 0xFF) && ((data[1] & 0xF0) == 0xF0)) {
858       isADTS = true;
859     }
860   }
861   status = codec->initDecoder(data, size, isADTS);
862   if (0 == status) {
863     int32_t bytesConsumed = 0;
864     status = codec->configXAACDecoder((uint8_t*)data, size, &bytesConsumed);
865     while ((int32_t)size > bytesConsumed) {
866       int32_t numOutBytes;
867       size -= bytesConsumed;
868       data += bytesConsumed;
869       status = codec->decodeXAACStream((uint8_t*)data, size, &bytesConsumed,
870                                        &numOutBytes);
871       num_proc_iterations++;
872       /* Stop processing after 500 frames */
873       if (num_proc_iterations > 500)
874         break;
875 
876       /* If decoder doesn't consume any bytes, advance by 4 bytes */
877       if (0 == bytesConsumed) bytesConsumed = 4;
878     }
879   }
880   status = codec->deInitXAACDecoder();
881   status = codec->deInitMPEGDDDrc();
882   delete codec;
883   return 0;
884 }
885