summaryrefslogtreecommitdiff
path: root/audio_codec/wfd_aac_decoder/decelmnt.c (plain)
blob: 4cd4ef8a4f8a0b04e876f2c98425be57349046b8
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: decelmnt.c,v 1.1.2.1 2005/02/26 02:05:12 jrecker Exp $
3 *
4 * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file,
7 * are subject to the current version of the RealNetworks Public
8 * Source License (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the current version of the RealNetworks Community
11 * Source License (the "RCSL") available at
12 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
13 * will apply. You may also obtain the license terms directly from
14 * RealNetworks. You may not use this file except in compliance with
15 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
16 * to this file, the RCSL. Please see the applicable RPSL or RCSL for
17 * the rights, obligations and limitations governing use of the
18 * contents of the file.
19 *
20 * This file is part of the Helix DNA Technology. RealNetworks is the
21 * developer of the Original Code and owns the copyrights in the
22 * portions it created.
23 *
24 * This file, and the files included with this file, is distributed
25 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
26 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
27 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
28 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
29 * ENJOYMENT OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * http://www.helixcommunity.org/content/tck
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**************************************************************************************
39 * Fixed-point HE-AAC decoder
40 * Jon Recker (jrecker@real.com)
41 * February 2005
42 *
43 * decelmnt.c - syntactic element decoding
44 **************************************************************************************/
45
46#include "coder.h"
47
48/**************************************************************************************
49 * Function: DecodeSingleChannelElement
50 *
51 * Description: decode one SCE
52 *
53 * Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4)
54 *
55 * Outputs: updated element instance tag
56 *
57 * Return: 0 if successful, -1 if error
58 *
59 * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
60 **************************************************************************************/
61static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
62{
63 /* validate pointers */
64 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
65 return -1;
66 }
67
68 /* read instance tag */
69 aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
70
71 return 0;
72}
73
74/**************************************************************************************
75 * Function: DecodeChannelPairElement
76 *
77 * Description: decode one CPE
78 *
79 * Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5)
80 *
81 * Outputs: updated element instance tag
82 * updated commonWin
83 * updated ICS info, if commonWin == 1
84 * updated mid-side stereo info, if commonWin == 1
85 *
86 * Return: 0 if successful, -1 if error
87 *
88 * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
89 **************************************************************************************/
90static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
91{
92 int sfb, gp, maskOffset;
93 unsigned char currBit, *maskPtr;
94 PSInfoBase *psi;
95 ICSInfo *icsInfo;
96
97 /* validate pointers */
98 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
99 return -1;
100 }
101 psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
102 icsInfo = psi->icsInfo;
103
104 /* read instance tag */
105 aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
106
107 /* read common window flag and mid-side info (if present)
108 * store msMask bits in psi->msMaskBits[] as follows:
109 * long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0]
110 * short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7]
111 * msMaskPresent = 0 means no M/S coding
112 * = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding
113 * = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed)
114 */
115 psi->commonWin = GetBits(bsi, 1);
116 if (psi->commonWin) {
117 DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx);
118 psi->msMaskPresent = GetBits(bsi, 2);
119 if (psi->msMaskPresent == 1) {
120 maskPtr = psi->msMaskBits;
121 *maskPtr = 0;
122 maskOffset = 0;
123 for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
124 for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
125 currBit = (unsigned char)GetBits(bsi, 1);
126 *maskPtr |= currBit << maskOffset;
127 if (++maskOffset == 8) {
128 maskPtr++;
129 *maskPtr = 0;
130 maskOffset = 0;
131 }
132 }
133 }
134 }
135 }
136
137 return 0;
138}
139
140/**************************************************************************************
141 * Function: DecodeLFEChannelElement
142 *
143 * Description: decode one LFE
144 *
145 * Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9)
146 *
147 * Outputs: updated element instance tag
148 *
149 * Return: 0 if successful, -1 if error
150 *
151 * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
152 **************************************************************************************/
153static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
154{
155 /* validate pointers */
156 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
157 return -1;
158 }
159
160 /* read instance tag */
161 aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
162
163 return 0;
164}
165
166/**************************************************************************************
167 * Function: DecodeDataStreamElement
168 *
169 * Description: decode one DSE
170 *
171 * Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10)
172 *
173 * Outputs: updated element instance tag
174 * filled in data stream buffer
175 *
176 * Return: 0 if successful, -1 if error
177 **************************************************************************************/
178static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
179{
180 unsigned int byteAlign, dataCount;
181 unsigned char *dataBuf;
182 PSInfoBase *psi;
183
184 /* validate pointers */
185 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
186 return -1;
187 }
188 psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
189
190 aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
191 byteAlign = GetBits(bsi, 1);
192 dataCount = GetBits(bsi, 8);
193 if (dataCount == 255) {
194 dataCount += GetBits(bsi, 8);
195 }
196
197 if (byteAlign) {
198 ByteAlignBitstream(bsi);
199 }
200
201 psi->dataCount = dataCount;
202 dataBuf = psi->dataBuf;
203 while (dataCount--) {
204 *dataBuf++ = GetBits(bsi, 8);
205 }
206
207 return 0;
208}
209
210/**************************************************************************************
211 * Function: DecodeProgramConfigElement
212 *
213 * Description: decode one PCE
214 *
215 * Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2)
216 *
217 * Outputs: filled-in ProgConfigElement struct
218 * updated BitStreamInfo struct
219 *
220 * Return: 0 if successful, error code (< 0) if error
221 *
222 * Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE
223 * (otherwise we just skip it in the bitstream, to save memory)
224 **************************************************************************************/
225int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi)
226{
227 int i;
228
229 pce->elemInstTag = GetBits(bsi, 4);
230 pce->profile = GetBits(bsi, 2);
231 pce->sampRateIdx = GetBits(bsi, 4);
232 pce->numFCE = GetBits(bsi, 4);
233 pce->numSCE = GetBits(bsi, 4);
234 pce->numBCE = GetBits(bsi, 4);
235 pce->numLCE = GetBits(bsi, 2);
236 pce->numADE = GetBits(bsi, 3);
237 pce->numCCE = GetBits(bsi, 4);
238
239 pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */
240 if (pce->monoMixdown) {
241 pce->monoMixdown |= GetBits(bsi, 4); /* element number */
242 }
243
244 pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */
245 if (pce->stereoMixdown) {
246 pce->stereoMixdown |= GetBits(bsi, 4); /* element number */
247 }
248
249 pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */
250 if (pce->matrixMixdown) {
251 pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */
252 pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */
253 }
254
255 for (i = 0; i < pce->numFCE; i++) {
256 pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
257 pce->fce[i] |= GetBits(bsi, 4); /* tag select */
258 }
259
260 for (i = 0; i < pce->numSCE; i++) {
261 pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
262 pce->sce[i] |= GetBits(bsi, 4); /* tag select */
263 }
264
265 for (i = 0; i < pce->numBCE; i++) {
266 pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
267 pce->bce[i] |= GetBits(bsi, 4); /* tag select */
268 }
269
270 for (i = 0; i < pce->numLCE; i++) {
271 pce->lce[i] = GetBits(bsi, 4); /* tag select */
272 }
273
274 for (i = 0; i < pce->numADE; i++) {
275 pce->ade[i] = GetBits(bsi, 4); /* tag select */
276 }
277
278 for (i = 0; i < pce->numCCE; i++) {
279 pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */
280 pce->cce[i] |= GetBits(bsi, 4); /* tag select */
281 }
282
283
284 ByteAlignBitstream(bsi);
285
286#ifdef KEEP_PCE_COMMENTS
287 pce->commentBytes = GetBits(bsi, 8);
288 for (i = 0; i < pce->commentBytes; i++) {
289 pce->commentField[i] = GetBits(bsi, 8);
290 }
291#else
292 /* eat comment bytes and throw away */
293 i = GetBits(bsi, 8);
294 while (i--) {
295 GetBits(bsi, 8);
296 }
297#endif
298
299 return 0;
300}
301
302/**************************************************************************************
303 * Function: DecodeFillElement
304 *
305 * Description: decode one fill element
306 *
307 * Inputs: BitStreamInfo struct pointing to start of fill element
308 * (14496-3, table 4.4.11)
309 *
310 * Outputs: updated element instance tag
311 * unpacked extension payload
312 *
313 * Return: 0 if successful, -1 if error
314 **************************************************************************************/
315static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
316{
317 unsigned int fillCount;
318 unsigned char *fillBuf;
319 PSInfoBase *psi;
320
321 /* validate pointers */
322 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
323 return -1;
324 }
325 psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
326
327 fillCount = GetBits(bsi, 4);
328 if (fillCount == 15) {
329 fillCount += (GetBits(bsi, 8) - 1);
330 }
331
332 psi->fillCount = fillCount;
333 fillBuf = psi->fillBuf;
334 while (fillCount--) {
335 *fillBuf++ = GetBits(bsi, 8);
336 }
337
338 aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */
339 aacDecInfo->fillExtType = 0;
340
341#ifdef AAC_ENABLE_SBR
342 /* check for SBR
343 * aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel
344 * need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and
345 * must upsample by 2 for LFE
346 */
347 if (psi->fillCount > 0) {
348 aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f);
349 if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) {
350 aacDecInfo->sbrEnabled = 1;
351 }
352 }
353#endif
354
355 aacDecInfo->fillBuf = psi->fillBuf;
356 aacDecInfo->fillCount = psi->fillCount;
357
358 return 0;
359}
360
361/**************************************************************************************
362 * Function: DecodeNextElement
363 *
364 * Description: decode next syntactic element in AAC frame
365 *
366 * Inputs: valid AACDecInfo struct
367 * double pointer to buffer containing next element
368 * pointer to bit offset
369 * pointer to number of valid bits remaining in buf
370 *
371 * Outputs: type of element decoded (aacDecInfo->currBlockID)
372 * type of element decoded last time (aacDecInfo->prevBlockID)
373 * updated aacDecInfo state, depending on which element was decoded
374 * updated buffer pointer
375 * updated bit offset
376 * updated number of available bits
377 *
378 * Return: 0 if successful, error code (< 0) if error
379 **************************************************************************************/
380int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail)
381{
382 int err, bitsUsed;
383 PSInfoBase *psi;
384 BitStreamInfo bsi;
385
386 /* validate pointers */
387 if (!aacDecInfo || !aacDecInfo->psInfoBase) {
388 return ERR_AAC_NULL_POINTER;
389 }
390 psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
391
392 /* init bitstream reader */
393 SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf);
394 GetBits(&bsi, *bitOffset);
395
396 /* read element ID (save last ID for SBR purposes) */
397 aacDecInfo->prevBlockID = aacDecInfo->currBlockID;
398 aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS);
399
400 /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */
401 psi->commonWin = 0;
402
403 err = 0;
404 switch (aacDecInfo->currBlockID) {
405 case AAC_ID_SCE:
406 err = DecodeSingleChannelElement(aacDecInfo, &bsi);
407 break;
408 case AAC_ID_CPE:
409 err = DecodeChannelPairElement(aacDecInfo, &bsi);
410 break;
411 case AAC_ID_CCE:
412 /* TODO - implement CCE decoding */
413 break;
414 case AAC_ID_LFE:
415 err = DecodeLFEChannelElement(aacDecInfo, &bsi);
416 break;
417 case AAC_ID_DSE:
418 err = DecodeDataStreamElement(aacDecInfo, &bsi);
419 break;
420 case AAC_ID_PCE:
421 err = DecodeProgramConfigElement(psi->pce + 0, &bsi);
422 break;
423 case AAC_ID_FIL:
424 err = DecodeFillElement(aacDecInfo, &bsi);
425 break;
426 case AAC_ID_END:
427 break;
428 }
429 if (err) {
430 return ERR_AAC_SYNTAX_ELEMENT;
431 }
432
433 /* update bitstream reader */
434 bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset);
435 *buf += (bitsUsed + *bitOffset) >> 3;
436 *bitOffset = (bitsUsed + *bitOffset) & 0x07;
437 *bitsAvail -= bitsUsed;
438
439 if (*bitsAvail < 0) {
440 return ERR_AAC_INDATA_UNDERFLOW;
441 }
442
443 return ERR_AAC_NONE;
444}
445
446