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 | **************************************************************************************/ |
61 | static 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 | **************************************************************************************/ |
90 | static 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 | **************************************************************************************/ |
153 | static 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 | **************************************************************************************/ |
178 | static 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 | **************************************************************************************/ |
225 | int 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 | **************************************************************************************/ |
315 | static 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 | **************************************************************************************/ |
380 | int 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 |