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