1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /**************************** AAC encoder library ******************************
96
97 Author(s): Markus Lohwasser
98
99 Description: Mpeg Surround library interface functions
100
101 *******************************************************************************/
102
103 /* Includes ******************************************************************/
104 #include "mps_main.h"
105 #include "sacenc_lib.h"
106
107 /* Data Types ****************************************************************/
108 struct MPS_ENCODER {
109 HANDLE_MP4SPACE_ENCODER hSacEncoder;
110
111 AUDIO_OBJECT_TYPE audioObjectType;
112
113 FDK_bufDescr inBufDesc;
114 FDK_bufDescr outBufDesc;
115 SACENC_InArgs inargs;
116 SACENC_OutArgs outargs;
117
118 void *pInBuffer[1];
119 UINT pInBufferSize[1];
120 UINT pInBufferElSize[1];
121 UINT pInBufferType[1];
122
123 void *pOutBuffer[2];
124 UINT pOutBufferSize[2];
125 UINT pOutBufferElSize[2];
126 UINT pOutBufferType[2];
127
128 UCHAR sacOutBuffer[1024]; /* Worst case memory consumption for ELDv2: 768
129 bytes => 6144 bits (Core + SBR + MPS) */
130 };
131
132 struct MPS_CONFIG_TAB {
133 AUDIO_OBJECT_TYPE audio_object_type;
134 CHANNEL_MODE channel_mode;
135 ULONG sbr_ratio;
136 ULONG sampling_rate;
137 ULONG bitrate_min;
138 ULONG bitrate_max;
139 };
140
141 /* Constants *****************************************************************/
142 static const MPS_CONFIG_TAB mpsConfigTab[] = {
143 {AOT_ER_AAC_ELD, MODE_212, 0, 16000, 16000, 39999},
144 {AOT_ER_AAC_ELD, MODE_212, 0, 22050, 16000, 49999},
145 {AOT_ER_AAC_ELD, MODE_212, 0, 24000, 16000, 61999},
146 {AOT_ER_AAC_ELD, MODE_212, 0, 32000, 20000, 84999},
147 {AOT_ER_AAC_ELD, MODE_212, 0, 44100, 50000, 192000},
148 {AOT_ER_AAC_ELD, MODE_212, 0, 48000, 62000, 192000},
149
150 {AOT_ER_AAC_ELD, MODE_212, 1, 16000, 18000, 31999},
151 {AOT_ER_AAC_ELD, MODE_212, 1, 22050, 18000, 31999},
152 {AOT_ER_AAC_ELD, MODE_212, 1, 24000, 20000, 64000},
153
154 {AOT_ER_AAC_ELD, MODE_212, 2, 32000, 18000, 64000},
155 {AOT_ER_AAC_ELD, MODE_212, 2, 44100, 21000, 64000},
156 {AOT_ER_AAC_ELD, MODE_212, 2, 48000, 26000, 64000}
157
158 };
159
160 /* Function / Class Declarations *********************************************/
161
162 /* Function / Class Definition ***********************************************/
163 static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
164 UCHAR *const pOutputBuffer,
165 const int outputBufferSize);
166
FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER * phMpsEnc)167 MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc) {
168 MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
169 HANDLE_MPS_ENCODER hMpsEnc = NULL;
170
171 if (phMpsEnc == NULL) {
172 error = MPS_ENCODER_INVALID_HANDLE;
173 goto bail;
174 }
175
176 if (NULL ==
177 (hMpsEnc = (HANDLE_MPS_ENCODER)FDKcalloc(1, sizeof(MPS_ENCODER)))) {
178 error = MPS_ENCODER_MEMORY_ERROR;
179 goto bail;
180 }
181 FDKmemclear(hMpsEnc, sizeof(MPS_ENCODER));
182
183 if (SACENC_OK != FDK_sacenc_open(&hMpsEnc->hSacEncoder)) {
184 error = MPS_ENCODER_MEMORY_ERROR;
185 goto bail;
186 }
187
188 /* Return mps encoder instance */
189 *phMpsEnc = hMpsEnc;
190
191 bail:
192 if (error != MPS_ENCODER_OK) {
193 FDK_MpegsEnc_Close(&hMpsEnc);
194 }
195 return error;
196 }
197
FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER * phMpsEnc)198 MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc) {
199 MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
200
201 if (phMpsEnc == NULL) {
202 error = MPS_ENCODER_INVALID_HANDLE;
203 goto bail;
204 }
205
206 if (*phMpsEnc != NULL) {
207 FDK_sacenc_close(&(*phMpsEnc)->hSacEncoder);
208 FDKfree(*phMpsEnc);
209 *phMpsEnc = NULL;
210 }
211 bail:
212 return error;
213 }
214
FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,const AUDIO_OBJECT_TYPE audioObjectType,const UINT samplingrate,const UINT bitrate,const UINT sbrRatio,const UINT framelength,const UINT inputBufferSizePerChannel,const UINT coreCoderDelay)215 MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,
216 const AUDIO_OBJECT_TYPE audioObjectType,
217 const UINT samplingrate, const UINT bitrate,
218 const UINT sbrRatio, const UINT framelength,
219 const UINT inputBufferSizePerChannel,
220 const UINT coreCoderDelay) {
221 MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
222 const UINT fs_low = 27713; /* low MPS sampling frequencies */
223 const UINT fs_high = 55426; /* high MPS sampling frequencies */
224 UINT nTimeSlots = 0, nQmfBandsLd = 0;
225
226 if (hMpsEnc == NULL) {
227 error = MPS_ENCODER_INVALID_HANDLE;
228 goto bail;
229 }
230
231 /* Combine MPS with SBR only if the number of QMF band fits together.*/
232 switch (sbrRatio) {
233 case 1: /* downsampled sbr - 32 QMF bands required */
234 if (!(samplingrate < fs_low)) {
235 error = MPS_ENCODER_INIT_ERROR;
236 goto bail;
237 }
238 break;
239 case 2: /* dualrate - 64 QMF bands required */
240 if (!((samplingrate >= fs_low) && (samplingrate < fs_high))) {
241 error = MPS_ENCODER_INIT_ERROR;
242 goto bail;
243 }
244 break;
245 case 0:
246 default:; /* time interface - no samplingrate restriction */
247 }
248
249 /* 32 QMF-Bands ( fs < 27713 )
250 * 64 QMF-Bands ( 27713 >= fs <= 55426 )
251 * 128 QMF-Bands ( fs > 55426 )
252 */
253 nQmfBandsLd =
254 (samplingrate < fs_low) ? 5 : ((samplingrate > fs_high) ? 7 : 6);
255 nTimeSlots = framelength >> nQmfBandsLd;
256
257 /* check if number of qmf bands is usable for given framelength */
258 if (framelength != (nTimeSlots << nQmfBandsLd)) {
259 error = MPS_ENCODER_INIT_ERROR;
260 goto bail;
261 }
262
263 /* is given bitrate intended to be supported */
264 if ((INT)bitrate != FDK_MpegsEnc_GetClosestBitRate(audioObjectType, MODE_212,
265 samplingrate, sbrRatio,
266 bitrate)) {
267 error = MPS_ENCODER_INIT_ERROR;
268 goto bail;
269 }
270
271 /* init SAC library */
272 switch (audioObjectType) {
273 case AOT_ER_AAC_ELD: {
274 const UINT noInterFrameCoding = 0;
275
276 if ((SACENC_OK !=
277 FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_LOWDELAY,
278 (noInterFrameCoding == 1) ? 1 : 2)) ||
279 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
280 SACENC_ENC_MODE, SACENC_212)) ||
281 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
282 SACENC_SAMPLERATE, samplingrate)) ||
283 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
284 SACENC_FRAME_TIME_SLOTS,
285 nTimeSlots)) ||
286 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
287 SACENC_PARAM_BANDS,
288 SACENC_BANDS_15)) ||
289 (SACENC_OK !=
290 FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_TIME_DOM_DMX, 2)) ||
291 (SACENC_OK !=
292 FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_COARSE_QUANT, 0)) ||
293 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
294 SACENC_QUANT_MODE,
295 SACENC_QUANTMODE_FINE)) ||
296 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
297 SACENC_TIME_ALIGNMENT, 0)) ||
298 (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
299 SACENC_INDEPENDENCY_FACTOR, 20))) {
300 error = MPS_ENCODER_INIT_ERROR;
301 goto bail;
302 }
303 break;
304 }
305 default:
306 error = MPS_ENCODER_INIT_ERROR;
307 goto bail;
308 }
309
310 if (SACENC_OK != FDK_sacenc_init(hMpsEnc->hSacEncoder, coreCoderDelay)) {
311 error = MPS_ENCODER_INIT_ERROR;
312 }
313
314 hMpsEnc->audioObjectType = audioObjectType;
315
316 hMpsEnc->inBufDesc.ppBase = (void **)&hMpsEnc->pInBuffer;
317 hMpsEnc->inBufDesc.pBufSize = hMpsEnc->pInBufferSize;
318 hMpsEnc->inBufDesc.pEleSize = hMpsEnc->pInBufferElSize;
319 hMpsEnc->inBufDesc.pBufType = hMpsEnc->pInBufferType;
320 hMpsEnc->inBufDesc.numBufs = 1;
321
322 hMpsEnc->outBufDesc.ppBase = (void **)&hMpsEnc->pOutBuffer;
323 hMpsEnc->outBufDesc.pBufSize = hMpsEnc->pOutBufferSize;
324 hMpsEnc->outBufDesc.pEleSize = hMpsEnc->pOutBufferElSize;
325 hMpsEnc->outBufDesc.pBufType = hMpsEnc->pOutBufferType;
326 hMpsEnc->outBufDesc.numBufs = 2;
327
328 hMpsEnc->pInBuffer[0] = NULL;
329 hMpsEnc->pInBufferSize[0] = 0;
330 hMpsEnc->pInBufferElSize[0] = sizeof(INT_PCM);
331 hMpsEnc->pInBufferType[0] = (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA);
332
333 hMpsEnc->pOutBuffer[0] = NULL;
334 hMpsEnc->pOutBufferSize[0] = 0;
335 hMpsEnc->pOutBufferElSize[0] = sizeof(INT_PCM);
336 hMpsEnc->pOutBufferType[0] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA);
337
338 hMpsEnc->pOutBuffer[1] = NULL;
339 hMpsEnc->pOutBufferSize[1] = 0;
340 hMpsEnc->pOutBufferElSize[1] = sizeof(UCHAR);
341 hMpsEnc->pOutBufferType[1] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA);
342
343 hMpsEnc->inargs.isInputInterleaved = 0;
344 hMpsEnc->inargs.inputBufferSizePerChannel = inputBufferSizePerChannel;
345
346 bail:
347 return error;
348 }
349
FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,INT_PCM * const pAudioSamples,const INT nAudioSamples,AACENC_EXT_PAYLOAD * pMpsExtPayload)350 MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,
351 INT_PCM *const pAudioSamples,
352 const INT nAudioSamples,
353 AACENC_EXT_PAYLOAD *pMpsExtPayload) {
354 MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
355
356 if (hMpsEnc == NULL) {
357 error = MPS_ENCODER_INVALID_HANDLE;
358 } else {
359 int sacHeaderFlag = 1;
360 int sacOutBufferOffset = 0;
361
362 /* In case of eld the ssc is explicit and doesn't need to be inband */
363 if (hMpsEnc->audioObjectType == AOT_ER_AAC_ELD) {
364 sacHeaderFlag = 0;
365 }
366
367 /* 4 bits nibble after extension type */
368 hMpsEnc->sacOutBuffer[0] = (sacHeaderFlag == 0) ? 0x3 : 0x7;
369 sacOutBufferOffset += 1;
370
371 if (sacHeaderFlag) {
372 sacOutBufferOffset += FDK_MpegsEnc_WriteFrameHeader(
373 hMpsEnc, &hMpsEnc->sacOutBuffer[sacOutBufferOffset],
374 sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset);
375 }
376
377 /* Register input and output buffer. */
378 hMpsEnc->pInBuffer[0] = (void *)pAudioSamples;
379 hMpsEnc->inargs.nInputSamples = nAudioSamples;
380
381 hMpsEnc->pOutBuffer[0] = (void *)pAudioSamples;
382 hMpsEnc->pOutBufferSize[0] = sizeof(INT_PCM) * nAudioSamples / 2;
383
384 hMpsEnc->pOutBuffer[1] = (void *)&hMpsEnc->sacOutBuffer[sacOutBufferOffset];
385 hMpsEnc->pOutBufferSize[1] =
386 sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset;
387
388 /* encode SAC frame */
389 if (SACENC_OK != FDK_sacenc_encode(hMpsEnc->hSacEncoder,
390 &hMpsEnc->inBufDesc,
391 &hMpsEnc->outBufDesc, &hMpsEnc->inargs,
392 &hMpsEnc->outargs)) {
393 error = MPS_ENCODER_ENCODE_ERROR;
394 goto bail;
395 }
396
397 /* export MPS payload */
398 pMpsExtPayload->pData = (UCHAR *)hMpsEnc->sacOutBuffer;
399 pMpsExtPayload->dataSize =
400 hMpsEnc->outargs.nOutputBits + 8 * (sacOutBufferOffset - 1);
401 pMpsExtPayload->dataType = EXT_LDSAC_DATA;
402 pMpsExtPayload->associatedChElement = -1;
403 }
404
405 bail:
406 return error;
407 }
408
FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,HANDLE_FDK_BITSTREAM hBs)409 INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,
410 HANDLE_FDK_BITSTREAM hBs) {
411 INT sscBits = 0;
412
413 if (NULL != hMpsEnc) {
414 MP4SPACEENC_INFO mp4SpaceEncoderInfo;
415 FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
416
417 if (hBs != NULL) {
418 int i;
419 int writtenBits = 0;
420 for (i = 0; i<mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits>> 3; i++) {
421 FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], 8);
422 writtenBits += 8;
423 }
424 FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i],
425 mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits - writtenBits);
426 } /* hBS */
427
428 sscBits = mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits;
429
430 } /* valid hMpsEnc */
431
432 return sscBits;
433 }
434
FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,UCHAR * const pOutputBuffer,const int outputBufferSize)435 static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
436 UCHAR *const pOutputBuffer,
437 const int outputBufferSize) {
438 const int sacTimeAlignFlag = 0;
439
440 /* Initialize variables */
441 int numBits = 0;
442
443 if ((NULL != hMpsEnc) && (NULL != pOutputBuffer)) {
444 UINT alignAnchor, cnt;
445 FDK_BITSTREAM Bs;
446 FDKinitBitStream(&Bs, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
447
448 /* Calculate SSC length information */
449 cnt = (FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, NULL) + 7) >> 3;
450
451 /* Write SSC */
452 FDKwriteBits(&Bs, sacTimeAlignFlag, 1);
453
454 if (cnt < 127) {
455 FDKwriteBits(&Bs, cnt, 7);
456 } else {
457 FDKwriteBits(&Bs, 127, 7);
458 FDKwriteBits(&Bs, cnt - 127, 16);
459 }
460
461 alignAnchor = FDKgetValidBits(&Bs);
462 FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, &Bs);
463 FDKbyteAlign(&Bs, alignAnchor); /* bsFillBits */
464
465 if (sacTimeAlignFlag) {
466 FDK_ASSERT(1); /* time alignment not supported */
467 }
468
469 numBits = FDKgetValidBits(&Bs);
470 } /* valid handle */
471
472 return ((numBits + 7) >> 3);
473 }
474
FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,const CHANNEL_MODE channelMode,const UINT samplingrate,const UINT sbrRatio,const UINT bitrate)475 INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,
476 const CHANNEL_MODE channelMode,
477 const UINT samplingrate, const UINT sbrRatio,
478 const UINT bitrate) {
479 unsigned int i;
480 int targetBitrate = -1;
481
482 for (i = 0; i < sizeof(mpsConfigTab) / sizeof(MPS_CONFIG_TAB); i++) {
483 if ((mpsConfigTab[i].audio_object_type == audioObjectType) &&
484 (mpsConfigTab[i].channel_mode == channelMode) &&
485 (mpsConfigTab[i].sbr_ratio == sbrRatio) &&
486 (mpsConfigTab[i].sampling_rate == samplingrate)) {
487 targetBitrate = fMin(fMax(bitrate, mpsConfigTab[i].bitrate_min),
488 mpsConfigTab[i].bitrate_max);
489 }
490 }
491
492 return targetBitrate;
493 }
494
FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc)495 INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc) {
496 INT delay = 0;
497
498 if (NULL != hMpsEnc) {
499 MP4SPACEENC_INFO mp4SpaceEncoderInfo;
500 FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
501 delay = mp4SpaceEncoderInfo.nCodecDelay;
502 }
503
504 return delay;
505 }
506
FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc)507 INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc) {
508 INT delay = 0;
509
510 if (NULL != hMpsEnc) {
511 MP4SPACEENC_INFO mp4SpaceEncoderInfo;
512 FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
513 delay = mp4SpaceEncoderInfo.nDecoderDelay;
514 }
515
516 return delay;
517 }
518
FDK_MpegsEnc_GetLibInfo(LIB_INFO * info)519 MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info) {
520 MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
521
522 if (NULL == info) {
523 error = MPS_ENCODER_INVALID_HANDLE;
524 } else if (SACENC_OK != FDK_sacenc_getLibInfo(info)) {
525 error = MPS_ENCODER_INIT_ERROR;
526 }
527
528 return error;
529 }
530