blob: 075174d2f0f73ef9c61d5035c73688145bd97acd
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: decelmnt.c,v 1.1 2005/02/26 01:47:34 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 | //#include <core/dsp.h> |
48 | #include <stdio.h> |
49 | #include "aacdec.h" |
50 | |
51 | /************************************************************************************** |
52 | * Function: DecodeSingleChannelElement |
53 | * |
54 | * Description: decode one SCE |
55 | * |
56 | * Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4) |
57 | * |
58 | * Outputs: updated element instance tag |
59 | * |
60 | * Return: 0 if successful, -1 if error |
61 | * |
62 | * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) |
63 | **************************************************************************************/ |
64 | static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) |
65 | { |
66 | /* validate pointers */ |
67 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
68 | return -1; |
69 | } |
70 | |
71 | /* read instance tag */ |
72 | aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); |
73 | |
74 | return 0; |
75 | } |
76 | |
77 | /************************************************************************************** |
78 | * Function: DecodeChannelPairElement |
79 | * |
80 | * Description: decode one CPE |
81 | * |
82 | * Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5) |
83 | * |
84 | * Outputs: updated element instance tag |
85 | * updated commonWin |
86 | * updated ICS info, if commonWin == 1 |
87 | * updated mid-side stereo info, if commonWin == 1 |
88 | * |
89 | * Return: 0 if successful, -1 if error |
90 | * |
91 | * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) |
92 | **************************************************************************************/ |
93 | static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) |
94 | { |
95 | int sfb, gp, maskOffset; |
96 | unsigned char currBit, *maskPtr; |
97 | PSInfoBase *psi; |
98 | ICSInfo *icsInfo; |
99 | |
100 | /* validate pointers */ |
101 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
102 | return -1; |
103 | } |
104 | psi = (PSInfoBase *)(aacDecInfo->psInfoBase); |
105 | icsInfo = psi->icsInfo; |
106 | |
107 | /* read instance tag */ |
108 | aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); |
109 | |
110 | /* read common window flag and mid-side info (if present) |
111 | * store msMask bits in psi->msMaskBits[] as follows: |
112 | * long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0] |
113 | * short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7] |
114 | * msMaskPresent = 0 means no M/S coding |
115 | * = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding |
116 | * = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed) |
117 | */ |
118 | psi->commonWin = GetBits(bsi, 1); |
119 | if (psi->commonWin) { |
120 | DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); |
121 | psi->msMaskPresent = GetBits(bsi, 2); |
122 | if (psi->msMaskPresent == 1) { |
123 | maskPtr = psi->msMaskBits; |
124 | *maskPtr = 0; |
125 | maskOffset = 0; |
126 | for (gp = 0; gp < icsInfo->numWinGroup; gp++) { |
127 | for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { |
128 | currBit = (unsigned char)GetBits(bsi, 1); |
129 | *maskPtr |= currBit << maskOffset; |
130 | if (++maskOffset == 8) { |
131 | maskPtr++; |
132 | *maskPtr = 0; |
133 | maskOffset = 0; |
134 | } |
135 | } |
136 | } |
137 | } |
138 | } |
139 | |
140 | return 0; |
141 | } |
142 | |
143 | /************************************************************************************** |
144 | * Function: DecodeLFEChannelElement |
145 | * |
146 | * Description: decode one LFE |
147 | * |
148 | * Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9) |
149 | * |
150 | * Outputs: updated element instance tag |
151 | * |
152 | * Return: 0 if successful, -1 if error |
153 | * |
154 | * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) |
155 | **************************************************************************************/ |
156 | static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) |
157 | { |
158 | /* validate pointers */ |
159 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
160 | return -1; |
161 | } |
162 | |
163 | /* read instance tag */ |
164 | aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); |
165 | |
166 | return 0; |
167 | } |
168 | |
169 | /************************************************************************************** |
170 | * Function: DecodeDataStreamElement |
171 | * |
172 | * Description: decode one DSE |
173 | * |
174 | * Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10) |
175 | * |
176 | * Outputs: updated element instance tag |
177 | * filled in data stream buffer |
178 | * |
179 | * Return: 0 if successful, -1 if error |
180 | **************************************************************************************/ |
181 | static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) |
182 | { |
183 | unsigned int byteAlign, dataCount; |
184 | unsigned char *dataBuf; |
185 | PSInfoBase *psi; |
186 | |
187 | /* validate pointers */ |
188 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
189 | return -1; |
190 | } |
191 | psi = (PSInfoBase *)(aacDecInfo->psInfoBase); |
192 | |
193 | aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); |
194 | byteAlign = GetBits(bsi, 1); |
195 | dataCount = GetBits(bsi, 8); |
196 | if (dataCount == 255) { |
197 | dataCount += GetBits(bsi, 8); |
198 | } |
199 | |
200 | if (byteAlign) { |
201 | ByteAlignBitstream(bsi); |
202 | } |
203 | |
204 | psi->dataCount = dataCount; |
205 | dataBuf = psi->dataBuf; |
206 | while (dataCount--) { |
207 | *dataBuf++ = GetBits(bsi, 8); |
208 | } |
209 | |
210 | return 0; |
211 | } |
212 | |
213 | /************************************************************************************** |
214 | * Function: DecodeProgramConfigElement |
215 | * |
216 | * Description: decode one PCE |
217 | * |
218 | * Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2) |
219 | * |
220 | * Outputs: filled-in ProgConfigElement struct |
221 | * updated BitStreamInfo struct |
222 | * |
223 | * Return: 0 if successful, error code (< 0) if error |
224 | * |
225 | * Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE |
226 | * (otherwise we just skip it in the bitstream, to save memory) |
227 | **************************************************************************************/ |
228 | int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi) |
229 | { |
230 | int i; |
231 | |
232 | pce->elemInstTag = GetBits(bsi, 4); |
233 | pce->profile = GetBits(bsi, 2); |
234 | pce->sampRateIdx = GetBits(bsi, 4); |
235 | pce->numFCE = GetBits(bsi, 4); |
236 | pce->numSCE = GetBits(bsi, 4); |
237 | pce->numBCE = GetBits(bsi, 4); |
238 | pce->numLCE = GetBits(bsi, 2); |
239 | pce->numADE = GetBits(bsi, 3); |
240 | pce->numCCE = GetBits(bsi, 4); |
241 | |
242 | pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */ |
243 | if (pce->monoMixdown) { |
244 | pce->monoMixdown |= GetBits(bsi, 4); /* element number */ |
245 | } |
246 | |
247 | pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */ |
248 | if (pce->stereoMixdown) { |
249 | pce->stereoMixdown |= GetBits(bsi, 4); /* element number */ |
250 | } |
251 | |
252 | pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */ |
253 | if (pce->matrixMixdown) { |
254 | pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */ |
255 | pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */ |
256 | } |
257 | |
258 | for (i = 0; i < pce->numFCE; i++) { |
259 | pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ |
260 | pce->fce[i] |= GetBits(bsi, 4); /* tag select */ |
261 | } |
262 | |
263 | for (i = 0; i < pce->numSCE; i++) { |
264 | pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ |
265 | pce->sce[i] |= GetBits(bsi, 4); /* tag select */ |
266 | } |
267 | |
268 | for (i = 0; i < pce->numBCE; i++) { |
269 | pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ |
270 | pce->bce[i] |= GetBits(bsi, 4); /* tag select */ |
271 | } |
272 | |
273 | for (i = 0; i < pce->numLCE; i++) { |
274 | pce->lce[i] = GetBits(bsi, 4); /* tag select */ |
275 | } |
276 | |
277 | for (i = 0; i < pce->numADE; i++) { |
278 | pce->ade[i] = GetBits(bsi, 4); /* tag select */ |
279 | } |
280 | |
281 | for (i = 0; i < pce->numCCE; i++) { |
282 | pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */ |
283 | pce->cce[i] |= GetBits(bsi, 4); /* tag select */ |
284 | } |
285 | |
286 | |
287 | ByteAlignBitstream(bsi); |
288 | |
289 | #ifdef KEEP_PCE_COMMENTS |
290 | pce->commentBytes = GetBits(bsi, 8); |
291 | for (i = 0; i < pce->commentBytes; i++) { |
292 | pce->commentField[i] = GetBits(bsi, 8); |
293 | } |
294 | #else |
295 | /* eat comment bytes and throw away */ |
296 | i = GetBits(bsi, 8); |
297 | while (i--) { |
298 | GetBits(bsi, 8); |
299 | } |
300 | #endif |
301 | |
302 | return 0; |
303 | } |
304 | |
305 | /************************************************************************************** |
306 | * Function: DecodeFillElement |
307 | * |
308 | * Description: decode one fill element |
309 | * |
310 | * Inputs: BitStreamInfo struct pointing to start of fill element |
311 | * (14496-3, table 4.4.11) |
312 | * |
313 | * Outputs: updated element instance tag |
314 | * unpacked extension payload |
315 | * |
316 | * Return: 0 if successful, -1 if error |
317 | **************************************************************************************/ |
318 | static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) |
319 | { |
320 | unsigned int fillCount; |
321 | unsigned char *fillBuf; |
322 | PSInfoBase *psi; |
323 | |
324 | /* validate pointers */ |
325 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
326 | return -1; |
327 | } |
328 | psi = (PSInfoBase *)(aacDecInfo->psInfoBase); |
329 | |
330 | fillCount = GetBits(bsi, 4); |
331 | if (fillCount == 15) { |
332 | fillCount += (GetBits(bsi, 8) - 1); |
333 | } |
334 | |
335 | psi->fillCount = fillCount; |
336 | fillBuf = psi->fillBuf; |
337 | while (fillCount--) { |
338 | *fillBuf++ = GetBits(bsi, 8); |
339 | } |
340 | |
341 | aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */ |
342 | aacDecInfo->fillExtType = 0; |
343 | |
344 | #ifdef AAC_ENABLE_SBR |
345 | /* check for SBR |
346 | * aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel |
347 | * need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and |
348 | * must upsample by 2 for LFE |
349 | */ |
350 | if (psi->fillCount > 0) { |
351 | aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f); |
352 | if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) { |
353 | aacDecInfo->sbrEnabled = 1; |
354 | } |
355 | } |
356 | #endif |
357 | |
358 | aacDecInfo->fillBuf = psi->fillBuf; |
359 | aacDecInfo->fillCount = psi->fillCount; |
360 | |
361 | return 0; |
362 | } |
363 | |
364 | /************************************************************************************** |
365 | * Function: DecodeNextElement |
366 | * |
367 | * Description: decode next syntactic element in AAC frame |
368 | * |
369 | * Inputs: valid AACDecInfo struct |
370 | * double pointer to buffer containing next element |
371 | * pointer to bit offset |
372 | * pointer to number of valid bits remaining in buf |
373 | * |
374 | * Outputs: type of element decoded (aacDecInfo->currBlockID) |
375 | * type of element decoded last time (aacDecInfo->prevBlockID) |
376 | * updated aacDecInfo state, depending on which element was decoded |
377 | * updated buffer pointer |
378 | * updated bit offset |
379 | * updated number of available bits |
380 | * |
381 | * Return: 0 if successful, error code (< 0) if error |
382 | **************************************************************************************/ |
383 | int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) |
384 | { |
385 | int err, bitsUsed; |
386 | PSInfoBase *psi; |
387 | BitStreamInfo bsi; |
388 | |
389 | /* validate pointers */ |
390 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
391 | return ERR_AAC_NULL_POINTER; |
392 | } |
393 | psi = (PSInfoBase *)(aacDecInfo->psInfoBase); |
394 | |
395 | /* init bitstream reader */ |
396 | if (AACDataSource == 1) { |
397 | SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); |
398 | GetBits(&bsi, *bitOffset); |
399 | } |
400 | |
401 | /* read element ID (save last ID for SBR purposes) */ |
402 | aacDecInfo->prevBlockID = aacDecInfo->currBlockID; |
403 | aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS); |
404 | |
405 | /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */ |
406 | psi->commonWin = 0; |
407 | |
408 | err = 0; |
409 | switch (aacDecInfo->currBlockID) { |
410 | case AAC_ID_SCE: |
411 | err = DecodeSingleChannelElement(aacDecInfo, &bsi); |
412 | break; |
413 | case AAC_ID_CPE: |
414 | err = DecodeChannelPairElement(aacDecInfo, &bsi); |
415 | break; |
416 | case AAC_ID_CCE: |
417 | /* TODO - implement CCE decoding */ |
418 | break; |
419 | case AAC_ID_LFE: |
420 | err = DecodeLFEChannelElement(aacDecInfo, &bsi); |
421 | break; |
422 | case AAC_ID_DSE: |
423 | err = DecodeDataStreamElement(aacDecInfo, &bsi); |
424 | break; |
425 | case AAC_ID_PCE: |
426 | err = DecodeProgramConfigElement(psi->pce + 0, &bsi); |
427 | break; |
428 | case AAC_ID_FIL: |
429 | err = DecodeFillElement(aacDecInfo, &bsi); |
430 | break; |
431 | case AAC_ID_END: |
432 | break; |
433 | } |
434 | if (err) { |
435 | return ERR_AAC_SYNTAX_ELEMENT; |
436 | } |
437 | |
438 | if (AACDataSource == 1) { |
439 | /* update bitstream reader */ |
440 | bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); |
441 | *buf += (bitsUsed + *bitOffset) >> 3; |
442 | *bitOffset = (bitsUsed + *bitOffset) & 0x07; |
443 | *bitsAvail -= bitsUsed; |
444 | |
445 | if (*bitsAvail < 0) { |
446 | return ERR_AAC_INDATA_UNDERFLOW; |
447 | } |
448 | } |
449 | return ERR_AAC_NONE; |
450 | } |
451 | |
452 |