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