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