summaryrefslogtreecommitdiff
path: root/audio_codec/libraac/aac_decode_main.c (plain)
blob: d184927fcc8c0ffef464c4554bbb92678fb2a8a7
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: aac_decode.c,v 1.2.2.1 2005/05/04 18:21:58 hubbe Exp $
3 *
4 * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM
5 * Portions Copyright (c) 1995-2005 RealNetworks, Inc.
6 * All Rights Reserved.
7 *
8 * The contents of this file, and the files included with this file,
9 * are subject to the current version of the Real Format Source Code
10 * Porting and Optimization License, available at
11 * https://helixcommunity.org/2005/license/realformatsource (unless
12 * RealNetworks otherwise expressly agrees in writing that you are
13 * subject to a different license). You may also obtain the license
14 * terms directly from RealNetworks. You may not use this file except
15 * in compliance with the Real Format Source Code Porting and
16 * Optimization License. There are no redistribution rights for the
17 * source code of this file. Please see the Real Format Source Code
18 * Porting and Optimization License for the rights, obligations and
19 * limitations governing use of the contents of the file.
20 *
21 * RealNetworks is the developer of the Original Code and owns the
22 * copyrights in the portions it created.
23 *
24 * This file, and the files included with this file, is distributed and
25 * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND,
26 * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL
27 * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT
29 * OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * https://rarvcode-tck.helixcommunity.org
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include <string.h>
39#include "include/helix_types.h"
40#include "include/helix_result.h"
41#include "aac_decode.h"
42#include "include/ra_format_info.h"
43#include "ga_config.h"
44#include "aac_bitstream.h"
45#include "aac_reorder.h"
46#include "aac_decode.h"
47#include "aacdec.h"
48#include <stdio.h>
49//#include <core/dsp.h>
50
51/*
52 * aac_decode_init
53 */
54HX_RESULT
55aac_decode_init(void* pInitParams,
56 UINT32 ulInitParamsSize,
57 ra_format_info* pStreamInfo,
58 void** pDecode,
59 void* pUserMem,
60 rm_malloc_func_ptr fpMalloc,
61 rm_free_func_ptr fpFree)
62{
63 HX_RESULT result = HXR_OK;
64 aac_decode* pDec;
65 AACFrameInfo *frameInfo;
66 ga_config_data configData;
67 UCHAR *pData;
68 UCHAR *inBuf;
69 INT16 *temp;
70 UINT32 numBytes, numBits;
71 UINT32 cfgType;
72
73 /* for MP4 bitstream parsing */
74 struct BITSTREAM *pBs = 0;
75
76 /* allocate the aac_decode struct */
77 pDec = (aac_decode*) fpMalloc(pUserMem, sizeof(aac_decode));
78 if (pDec == HXNULL) {
79 return HXR_OUTOFMEMORY;
80 }
81
82 memset(pDec, 0, sizeof(aac_decode));
83 *pDecode = (void *)pDec;
84
85 /* allocate the frame info struct */
86 pDec->pFrameInfo = fpMalloc(pUserMem, sizeof(AACFrameInfo));
87 frameInfo = (AACFrameInfo *) pDec->pFrameInfo;
88 /* allocate the decoder backend instance */
89 pDec->pDecoder = AACInitDecoder(1);
90 if (pDec->pFrameInfo == HXNULL || pDec->pDecoder == HXNULL) {
91 return HXR_OUTOFMEMORY;
92 }
93
94 /* save the stream info and init data we'll need later */
95 pDec->ulNumChannels = (UINT32)pStreamInfo->usNumChannels;
96 pDec->ulBlockSize = pStreamInfo->ulGranularity;
97 pDec->ulFrameSize = pStreamInfo->ulBitsPerFrame;
98 pDec->ulFramesPerBlock = pDec->ulBlockSize / pDec->ulFrameSize;
99 /* output frame size is doubled for safety in case of implicit SBR */
100 pDec->ulSamplesPerFrame = 1024 * pStreamInfo->usNumChannels * 2;
101 pDec->ulSampleRateCore = pStreamInfo->ulSampleRate;
102 pDec->ulSampleRateOut = pStreamInfo->ulActualRate;
103 if (pStreamInfo->ulOpaqueDataSize < 1) {
104 return HXR_FAIL; /* insufficient config data */
105 }
106
107 /* get the config data */
108 pData = (UCHAR *)pStreamInfo->pOpaqueData;
109 cfgType = pData[0];
110 inBuf = pData + 1;
111 numBytes = pStreamInfo->ulOpaqueDataSize - 1;
112
113 if (cfgType == 1) { /* ADTS Frame */
114 /* allocate temp buffer for decoding first ADTS frame */
115 temp = (INT16 *)fpMalloc(pUserMem, sizeof(INT16) * pDec->ulSamplesPerFrame);
116 if (temp == HXNULL) {
117 return HXR_OUTOFMEMORY;
118 } else {
119 /* decode ADTS frame from opaque data to get config data */
120 result = AACDecode(pDec->pDecoder, &inBuf, (INT32*)&numBytes, temp);
121 /* free the temp buffer */
122 fpFree(pUserMem, temp);
123 }
124
125 if (result == HXR_OK) {
126 /* get the config data struct from the decoder */
127 AACGetLastFrameInfo(pDec->pDecoder, frameInfo);
128
129 pDec->ulNumChannels = frameInfo->nChans;
130 pDec->ulSamplesPerFrame = frameInfo->outputSamps;
131 pDec->ulSampleRateCore = frameInfo->sampRateCore;
132 pDec->ulSampleRateOut = frameInfo->sampRateOut;
133 pDec->bSBR = (pDec->ulSampleRateCore != pDec->ulSampleRateOut);
134 }
135 } else if (cfgType == 2) { /* MP4 Audio Specific Config Data */
136 numBits = numBytes * 8;
137
138 if (newBitstream(&pBs, numBits, pUserMem, fpMalloc)) {
139 return HXR_FAIL;
140 }
141
142 feedBitstream(pBs, (const UCHAR *)inBuf, numBits);
143 setAtBitstream(pBs, 0, 1);
144 result = ga_config_get_data(pBs, &configData);
145 deleteBitstream(pBs, pUserMem, fpFree);
146 if (result != HXR_OK) { /* config data error */
147 return HXR_FAIL;
148 }
149
150 pDec->ulNumChannels = configData.numChannels;
151 pDec->ulSampleRateCore = configData.samplingFrequency;
152 pDec->ulSampleRateOut = configData.extensionSamplingFrequency;
153 pDec->bSBR = configData.bSBR;
154
155 /* ulSamplesPerFrame is set to the maximum possible output length.
156 * The config data has the initial output length, which might
157 * be doubled once the first frame is handed in (if AAC+ is
158 * signalled implicitly).
159 */
160 pDec->ulSamplesPerFrame = 2 * configData.frameLength * configData.numChannels;
161
162 /* setup decoder to handle raw data blocks */
163 frameInfo->nChans = pDec->ulNumChannels;
164 frameInfo->sampRateCore = pDec->ulSampleRateCore;
165
166 /* see MPEG4 spec for index of each object type */
167 if (configData.audioObjectType == 2) {
168 frameInfo->profile = AAC_PROFILE_LC;
169 } else if (configData.audioObjectType == 1) {
170 frameInfo->profile = AAC_PROFILE_MP;
171 } else if (configData.audioObjectType == 3) {
172 frameInfo->profile = AAC_PROFILE_SSR;
173 } else {
174 frameInfo->profile = AAC_PROFILE_LC; /* don't know - assume LC */
175 }
176 frameInfo->audio_send_by_frame = 0;
177 } else { /* unsupported config type */
178 return HXR_FAIL;
179 }
180
181 /* make certain that all the channels can be handled */
182 if (pDec->ulNumChannels > AAC_MAX_NCHANS) {
183 return HXR_UNSUPPORTED_AUDIO;
184 }
185
186 /* set the channel mask - custom maps not supported */
187 switch (pDec->ulNumChannels) {
188 case 1:
189 pDec->ulChannelMask = 0x00004; /* FC */
190 case 2:
191 pDec->ulChannelMask = 0x00003; /* FL,FR */
192 case 3:
193 pDec->ulChannelMask = 0x00007; /* FL,FR,FC */
194 case 4:
195 pDec->ulChannelMask = 0x00107; /* FL,FR,FC,BC */
196 case 5:
197 pDec->ulChannelMask = 0x00037; /* FL,FR,FC,BL,BR */
198 case 6:
199 pDec->ulChannelMask = 0x0003F; /* FL,FR,FC,LF,BL,BR */
200 default:
201 pDec->ulChannelMask = 0xFFFFF; /* Unknown */
202 }
203
204 /* set the delay samples */
205 pDec->ulDelayRemaining = pDec->ulSamplesPerFrame;
206
207 /* set decoder to handle raw data blocks */
208 AACSetRawBlockParams(pDec->pDecoder, 0, frameInfo);
209
210
211 return HXR_OK;
212}
213
214HX_RESULT
215aac_decode_reset(void* pDecode,
216 UINT16* pSamplesOut,
217 UINT32 ulNumSamplesAvail,
218 UINT32* pNumSamplesOut)
219{
220 aac_decode* pDec = (aac_decode*) pDecode;
221 AACFlushCodec(pDec->pDecoder);
222 *pNumSamplesOut = 0;
223 pDec->ulSamplesToConceal = 0;
224
225 /* reset the delay compensation */
226 pDec->ulDelayRemaining = pDec->ulSamplesPerFrame;
227
228 return HXR_OK;
229}
230
231HX_RESULT
232aac_decode_conceal(void* pDecode,
233 UINT32 ulNumSamples)
234{
235 aac_decode* pDec = (aac_decode*) pDecode;
236 if (pDec->bSBR) {
237 pDec->ulSamplesToConceal = (ulNumSamples + 2 * AAC_MAX_NSAMPS - 1) / (2 * AAC_MAX_NSAMPS);
238 } else {
239 pDec->ulSamplesToConceal = (ulNumSamples + AAC_MAX_NSAMPS - 1) / AAC_MAX_NSAMPS;
240 }
241
242 return HXR_OK;
243}
244
245HX_RESULT
246aac_decode_decode(void* pDecode,
247 UINT8* pData,
248 UINT32 ulNumBytes,
249 UINT32* pNumBytesConsumed,
250 UINT16* pSamplesOut,
251 UINT32 ulNumSamplesAvail,
252 UINT32* pNumSamplesOut,
253 UINT32 ulFlags,
254 UINT32 ulTimeStamp)
255{
256 HX_RESULT retVal = HXR_FAIL;
257 aac_decode* pDec = (aac_decode*) pDecode;
258 AACFrameInfo *frameInfo = pDec->pFrameInfo;
259 UINT32 lostFlag, maxSamplesOut;
260 UINT32 ulNumBytesRemaining;
261 UINT8* inBuf = pData;
262 UINT16* outBuf = pSamplesOut;
263
264 ulNumBytesRemaining = ulNumBytes;
265 *pNumBytesConsumed = 0;
266 *pNumSamplesOut = 0;
267
268 lostFlag = !(ulFlags & 1);
269
270 if (pDec->ulSamplesToConceal || lostFlag) {
271 if (lostFlag) { /* conceal one frame */
272 *pNumSamplesOut = pDec->ulSamplesPerFrame;
273 } else {
274 maxSamplesOut = pDec->ulSamplesPerFrame * pDec->ulFramesPerBlock;
275 *pNumSamplesOut = maxSamplesOut;
276 if (pDec->ulSamplesToConceal < maxSamplesOut) {
277 *pNumSamplesOut = pDec->ulSamplesToConceal;
278 }
279 pDec->ulSamplesToConceal -= *pNumSamplesOut;
280 }
281 /* just fill with silence */
282 memset(pSamplesOut, 0, *pNumSamplesOut * sizeof(INT16));
283 AACFlushCodec(pDec->pDecoder);
284
285 *pNumBytesConsumed = 0;
286 return HXR_OK;
287 }
288
289 retVal = AACDecode(pDec->pDecoder, &inBuf,
290 (INT32*)&ulNumBytesRemaining, (INT16*)outBuf);
291 if (retVal == ERR_AAC_NONE) {
292 AACGetLastFrameInfo(pDec->pDecoder, frameInfo);
293 AACReorderPCMChannels((INT16*)outBuf, frameInfo->outputSamps, frameInfo->nChans);
294 pDec->ulSampleRateCore = frameInfo->sampRateCore;
295 pDec->ulSampleRateOut = frameInfo->sampRateOut;
296 pDec->ulNumChannels = frameInfo->nChans;
297 *pNumSamplesOut = frameInfo->outputSamps;
298 *pNumBytesConsumed = ulNumBytes - ulNumBytesRemaining;
299 retVal = HXR_OK;
300 } else if (retVal == ERR_AAC_INDATA_UNDERFLOW) {
301 retVal = HXR_NO_DATA;
302 } else {
303 retVal = HXR_FAIL;
304 }
305
306 /* Zero out invalid output samples */
307 if (*pNumSamplesOut == 0) {
308 /* protect consumer ears by zeroing the output buffer */
309 memset(pSamplesOut, 0, pDec->ulSamplesPerFrame * sizeof(UINT16));
310 } else if (pDec->ulDelayRemaining > 0) { /* delay samples */
311 if (pDec->ulDelayRemaining >= *pNumSamplesOut) {
312 pDec->ulDelayRemaining -= *pNumSamplesOut;
313 *pNumSamplesOut = 0;
314 } else {
315 *pNumSamplesOut -= pDec->ulDelayRemaining;
316 memmove(pSamplesOut, pSamplesOut + pDec->ulDelayRemaining, *pNumSamplesOut);
317 pDec->ulDelayRemaining = 0;
318 }
319 }
320
321 return retVal;
322}
323
324HX_RESULT
325aac_decode_getmaxsize(void* pDecode,
326 UINT32* pNumSamples)
327{
328 aac_decode* pDec = (aac_decode *)pDecode;
329 *pNumSamples = pDec->ulSamplesPerFrame * pDec->ulFramesPerBlock;
330
331 return HXR_OK;
332}
333
334HX_RESULT
335aac_decode_getchannels(void* pDecode,
336 UINT32* pNumChannels)
337{
338 aac_decode* pDec = (aac_decode *)pDecode;
339 *pNumChannels = pDec->ulNumChannels;
340
341 return HXR_OK;
342}
343
344HX_RESULT
345aac_decode_getchannelmask(void* pDecode,
346 UINT32* pChannelMask)
347{
348 aac_decode* pDec = (aac_decode *)pDecode;
349 *pChannelMask = pDec->ulChannelMask;
350
351 return HXR_OK;
352}
353
354HX_RESULT
355aac_decode_getrate(void* pDecode,
356 UINT32* pSampleRate)
357{
358 aac_decode* pDec = (aac_decode *)pDecode;
359 *pSampleRate = pDec->ulSampleRateOut;
360
361 return HXR_OK;
362}
363
364HX_RESULT
365aac_decode_getdelay(void* pDecode,
366 UINT32* pNumSamples)
367{
368 aac_decode* pDec = (aac_decode *)pDecode;
369 /* delay compensation is handled internally */
370 *pNumSamples = 0;
371
372 return HXR_OK;
373}
374
375HX_RESULT
376aac_decode_close(void* pDecode,
377 void* pUserMem,
378 rm_free_func_ptr fpFree)
379{
380 aac_decode* pDec = (aac_decode *)pDecode;
381 /* free the aac decoder */
382 if (pDec->pDecoder) {
383 AACFreeDecoder(pDec->pDecoder);
384 pDec->pDecoder = HXNULL;
385 }
386 /* free the frame info struct */
387 if (pDec->pFrameInfo) {
388 fpFree(pUserMem, pDec->pFrameInfo);
389 pDec->pFrameInfo = HXNULL;
390 }
391 /* free the aac backend */
392 fpFree(pUserMem, pDec);
393 pDec = HXNULL;
394
395 return HXR_OK;
396}
397