OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
bitstream.c
Go to the documentation of this file.
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: RCSL 1.0/RPSL 1.0
3 *
4 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file, are
7 * subject to the current version of the RealNetworks Public Source License
8 * Version 1.0 (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the RealNetworks Community Source License Version 1.0
11 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
12 * in which case the RCSL will apply. You may also obtain the license terms
13 * directly from RealNetworks. You may not use this file except in
14 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
15 * applicable to this file, the RCSL. Please see the applicable RPSL or
16 * RCSL for the rights, obligations and limitations governing use of the
17 * contents of the file.
18 *
19 * This file is part of the Helix DNA Technology. RealNetworks is the
20 * developer of the Original Code and owns the copyrights in the portions
21 * it created.
22 *
23 * This file, and the files included with this file, is distributed and made
24 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
25 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
26 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
27 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
28 *
29 * Technology Compatibility Kit Test Suite(s) Location:
30 * http://www.helixcommunity.org/content/tck
31 *
32 * Contributor(s):
33 *
34 * ***** END LICENSE BLOCK ***** */
35
36/**************************************************************************************
37 * Fixed-point MP3 decoder
38 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
39 * June 2003
40 *
41 * bitstream.c - bitstream unpacking, frame header parsing, side info parsing
42 **************************************************************************************/
43
44#include "coder.h"
45#include "assembly.h"
46
47/**************************************************************************************
48 * Function: SetBitstreamPointer
49 *
50 * Description: initialize bitstream reader
51 *
52 * Inputs: pointer to BitStreamInfo struct
53 * number of bytes in bitstream
54 * pointer to byte-aligned buffer of data to read from
55 *
56 * Outputs: filled bitstream info struct
57 *
58 * Return: none
59 **************************************************************************************/
60void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf)
61{
62 /* init bitstream */
63 bsi->bytePtr = buf;
64 bsi->iCache = 0; /* 4-byte unsigned int */
65 bsi->cachedBits = 0; /* i.e. zero bits in cache */
66 bsi->nBytes = nBytes;
67}
68
69/**************************************************************************************
70 * Function: RefillBitstreamCache
71 *
72 * Description: read new data from bitstream buffer into bsi cache
73 *
74 * Inputs: pointer to initialized BitStreamInfo struct
75 *
76 * Outputs: updated bitstream info struct
77 *
78 * Return: none
79 *
80 * Notes: only call when iCache is completely drained (resets bitOffset to 0)
81 * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer)
82 * stores data as big-endian in cache, regardless of machine endian-ness
83 *
84 * TODO: optimize for ARM
85 * possibly add little/big-endian modes for doing 32-bit loads
86 **************************************************************************************/
87static __inline void RefillBitstreamCache(BitStreamInfo *bsi)
88{
89 int nBytes = bsi->nBytes;
90
91 /* optimize for common case, independent of machine endian-ness */
92 if (nBytes >= 4) {
93 bsi->iCache = (*bsi->bytePtr++) << 24;
94 bsi->iCache |= (*bsi->bytePtr++) << 16;
95 bsi->iCache |= (*bsi->bytePtr++) << 8;
96 bsi->iCache |= (*bsi->bytePtr++);
97 bsi->cachedBits = 32;
98 bsi->nBytes -= 4;
99 } else {
100 bsi->iCache = 0;
101 while (nBytes--) {
102 bsi->iCache |= (*bsi->bytePtr++);
103 bsi->iCache <<= 8;
104 }
105 bsi->iCache <<= ((3 - bsi->nBytes)*8);
106 bsi->cachedBits = 8*bsi->nBytes;
107 bsi->nBytes = 0;
108 }
109}
110
111/**************************************************************************************
112 * Function: GetBits
113 *
114 * Description: get bits from bitstream, advance bitstream pointer
115 *
116 * Inputs: pointer to initialized BitStreamInfo struct
117 * number of bits to get from bitstream
118 *
119 * Outputs: updated bitstream info struct
120 *
121 * Return: the next nBits bits of data from bitstream buffer
122 *
123 * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
124 * for speed, does not indicate error if you overrun bit buffer
125 * if nBits = 0, returns 0 (useful for scalefactor unpacking)
126 *
127 * TODO: optimize for ARM
128 **************************************************************************************/
129unsigned int GetBits(BitStreamInfo *bsi, int nBits)
130{
131 unsigned int data, lowBits;
132
133 nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
134 data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
135 data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
136 bsi->iCache <<= nBits; /* left-justify cache */
137 bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */
138
139 /* if we cross an int boundary, refill the cache */
140 if (bsi->cachedBits < 0) {
141 lowBits = -bsi->cachedBits;
142 RefillBitstreamCache(bsi);
143 data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */
144
145 bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */
146 bsi->iCache <<= lowBits; /* left-justify cache */
147 }
148
149 return data;
150}
151
152/**************************************************************************************
153 * Function: CalcBitsUsed
154 *
155 * Description: calculate how many bits have been read from bitstream
156 *
157 * Inputs: pointer to initialized BitStreamInfo struct
158 * pointer to start of bitstream buffer
159 * bit offset into first byte of startBuf (0-7)
160 *
161 * Outputs: none
162 *
163 * Return: number of bits read from bitstream, as offset from startBuf:startOffset
164 **************************************************************************************/
165int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset)
166{
167 int bitsUsed;
168
169 bitsUsed = (int)(bsi->bytePtr - startBuf) * 8;
170 bitsUsed -= bsi->cachedBits;
171 bitsUsed -= startOffset;
172
173 return bitsUsed;
174}
175
176/**************************************************************************************
177 * Function: CheckPadBit
178 *
179 * Description: check whether padding byte is present in an MP3 frame
180 *
181 * Inputs: MP3DecInfo struct with valid FrameHeader struct
182 * (filled by UnpackFrameHeader())
183 *
184 * Outputs: none
185 *
186 * Return: 1 if pad bit is set, 0 if not, -1 if null input pointer
187 **************************************************************************************/
188int CheckPadBit(MP3DecInfo *mp3DecInfo)
189{
190 FrameHeader *fh;
191
192 /* validate pointers */
193 if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS)
194 return -1;
195
196 fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
197
198 return (fh->paddingBit ? 1 : 0);
199}
200
201/**************************************************************************************
202 * Function: UnpackFrameHeader
203 *
204 * Description: parse the fields of the MP3 frame header
205 *
206 * Inputs: buffer pointing to a complete MP3 frame header (4 bytes, plus 2 if CRC)
207 *
208 * Outputs: filled frame header info in the MP3DecInfo structure
209 * updated platform-specific FrameHeader struct
210 *
211 * Return: length (in bytes) of frame header (for caller to calculate offset to
212 * first byte following frame header)
213 * -1 if null frameHeader or invalid header
214 *
215 * TODO: check for valid modes, depending on capabilities of decoder
216 * test CRC on actual stream (verify no endian problems)
217 **************************************************************************************/
218int UnpackFrameHeader(MP3DecInfo *mp3DecInfo, unsigned char *buf)
219{
220
221 int verIdx;
222 FrameHeader *fh;
223
224 /* validate pointers and sync word */
225 if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || (buf[0] & SYNCWORDH) != SYNCWORDH || (buf[1] & SYNCWORDL) != SYNCWORDL)
226 return -1;
227
228 fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
229
230 /* read header fields - use bitmasks instead of GetBits() for speed, since format never varies */
231 verIdx = (buf[1] >> 3) & 0x03;
232 fh->ver = (MPEGVersion)( verIdx == 0 ? MPEG25 : ((verIdx & 0x01) ? MPEG1 : MPEG2) );
233 fh->layer = 4 - ((buf[1] >> 1) & 0x03); /* easy mapping of index to layer number, 4 = error */
234 fh->crc = 1 - ((buf[1] >> 0) & 0x01);
235 fh->brIdx = (buf[2] >> 4) & 0x0f;
236 fh->srIdx = (buf[2] >> 2) & 0x03;
237 fh->paddingBit = (buf[2] >> 1) & 0x01;
238 fh->privateBit = (buf[2] >> 0) & 0x01;
239 fh->sMode = (StereoMode)((buf[3] >> 6) & 0x03); /* maps to correct enum (see definition) */
240 fh->modeExt = (buf[3] >> 4) & 0x03;
241 fh->copyFlag = (buf[3] >> 3) & 0x01;
242 fh->origFlag = (buf[3] >> 2) & 0x01;
243 fh->emphasis = (buf[3] >> 0) & 0x03;
244
245 /* check parameters to avoid indexing tables with bad values */
246 if (fh->srIdx == 3 || fh->layer == 4 || fh->brIdx == 15)
247 return -1;
248
249 fh->sfBand = &sfBandTable[fh->ver][fh->srIdx]; /* for readability (we reference sfBandTable many times in decoder) */
250 if (fh->sMode != Joint) /* just to be safe (dequant, stproc check fh->modeExt) */
251 fh->modeExt = 0;
252
253 /* init user-accessible data */
254 mp3DecInfo->nChans = (fh->sMode == Mono ? 1 : 2);
255 mp3DecInfo->samprate = samplerateTab[fh->ver][fh->srIdx];
256 mp3DecInfo->nGrans = (fh->ver == MPEG1 ? NGRANS_MPEG1 : NGRANS_MPEG2);
257 mp3DecInfo->nGranSamps = ((int)samplesPerFrameTab[fh->ver][fh->layer - 1]) / mp3DecInfo->nGrans;
258 mp3DecInfo->layer = fh->layer;
259 mp3DecInfo->version = fh->ver;
260
261 /* get bitrate and nSlots from table, unless brIdx == 0 (free mode) in which case caller must figure it out himself
262 * question - do we want to overwrite mp3DecInfo->bitrate with 0 each time if it's free mode, and
263 * copy the pre-calculated actual free bitrate into it in mp3dec.c (according to the spec,
264 * this shouldn't be necessary, since it should be either all frames free or none free)
265 */
266 if (fh->brIdx) {
267 mp3DecInfo->bitrate = ((int)bitrateTab[fh->ver][fh->layer - 1][fh->brIdx]) * 1000;
268
269 /* nSlots = total frame bytes (from table) - sideInfo bytes - header - CRC (if present) + pad (if present) */
270 mp3DecInfo->nSlots = (int)slotTab[fh->ver][fh->srIdx][fh->brIdx] -
271 (int)sideBytesTab[fh->ver][(fh->sMode == Mono ? 0 : 1)] -
272 4 - (fh->crc ? 2 : 0) + (fh->paddingBit ? 1 : 0);
273 } else {
274 /* do not support free mode */
275 return -1;
276 }
277
278 /* load crc word, if enabled, and return length of frame header (in bytes) */
279 if (fh->crc) {
280 fh->CRCWord = ((int)buf[4] << 8 | (int)buf[5] << 0);
281 return 6;
282 } else {
283 fh->CRCWord = 0;
284 return 4;
285 }
286}
287
288/**************************************************************************************
289 * Function: UnpackSideInfo
290 *
291 * Description: parse the fields of the MP3 side info header
292 *
293 * Inputs: MP3DecInfo structure filled by UnpackFrameHeader()
294 * buffer pointing to the MP3 side info data
295 *
296 * Outputs: updated mainDataBegin in MP3DecInfo struct
297 * updated private (platform-specific) SideInfo struct
298 *
299 * Return: length (in bytes) of side info data
300 * -1 if null input pointers
301 **************************************************************************************/
302int UnpackSideInfo(MP3DecInfo *mp3DecInfo, unsigned char *buf)
303{
304 int gr, ch, bd, nBytes;
305 BitStreamInfo bitStreamInfo, *bsi;
306 FrameHeader *fh;
307 SideInfo *si;
308 SideInfoSub *sis;
309
310 /* validate pointers and sync word */
311 if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS)
312 return -1;
313
314 fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
315 si = ((SideInfo *)(mp3DecInfo->SideInfoPS));
316
317 bsi = &bitStreamInfo;
318 if (fh->ver == MPEG1) {
319 /* MPEG 1 */
321 SetBitstreamPointer(bsi, nBytes, buf);
322 si->mainDataBegin = GetBits(bsi, 9);
323 si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 5 : 3));
324
325 for (ch = 0; ch < mp3DecInfo->nChans; ch++)
326 for (bd = 0; bd < MAX_SCFBD; bd++)
327 si->scfsi[ch][bd] = GetBits(bsi, 1);
328 } else {
329 /* MPEG 2, MPEG 2.5 */
331 SetBitstreamPointer(bsi, nBytes, buf);
332 si->mainDataBegin = GetBits(bsi, 8);
333 si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 1 : 2));
334 }
335
336 for(gr =0; gr < mp3DecInfo->nGrans; gr++) {
337 for (ch = 0; ch < mp3DecInfo->nChans; ch++) {
338 sis = &si->sis[gr][ch]; /* side info subblock for this granule, channel */
339
340 sis->part23Length = GetBits(bsi, 12);
341 sis->nBigvals = GetBits(bsi, 9);
342 sis->globalGain = GetBits(bsi, 8);
343 sis->sfCompress = GetBits(bsi, (fh->ver == MPEG1 ? 4 : 9));
344 sis->winSwitchFlag = GetBits(bsi, 1);
345
346 if(sis->winSwitchFlag) {
347 /* this is a start, stop, short, or mixed block */
348 sis->blockType = GetBits(bsi, 2); /* 0 = normal, 1 = start, 2 = short, 3 = stop */
349 sis->mixedBlock = GetBits(bsi, 1); /* 0 = not mixed, 1 = mixed */
350 sis->tableSelect[0] = GetBits(bsi, 5);
351 sis->tableSelect[1] = GetBits(bsi, 5);
352 sis->tableSelect[2] = 0; /* unused */
353 sis->subBlockGain[0] = GetBits(bsi, 3);
354 sis->subBlockGain[1] = GetBits(bsi, 3);
355 sis->subBlockGain[2] = GetBits(bsi, 3);
356
357 /* TODO - check logic */
358 if (sis->blockType == 0) {
359 /* this should not be allowed, according to spec */
360 sis->nBigvals = 0;
361 sis->part23Length = 0;
362 sis->sfCompress = 0;
363 } else if (sis->blockType == 2 && sis->mixedBlock == 0) {
364 /* short block, not mixed */
365 sis->region0Count = 8;
366 } else {
367 /* start, stop, or short-mixed */
368 sis->region0Count = 7;
369 }
370 sis->region1Count = 20 - sis->region0Count;
371 } else {
372 /* this is a normal block */
373 sis->blockType = 0;
374 sis->mixedBlock = 0;
375 sis->tableSelect[0] = GetBits(bsi, 5);
376 sis->tableSelect[1] = GetBits(bsi, 5);
377 sis->tableSelect[2] = GetBits(bsi, 5);
378 sis->region0Count = GetBits(bsi, 4);
379 sis->region1Count = GetBits(bsi, 3);
380 }
381 sis->preFlag = (fh->ver == MPEG1 ? GetBits(bsi, 1) : 0);
382 sis->sfactScale = GetBits(bsi, 1);
383 sis->count1TableSelect = GetBits(bsi, 1);
384 }
385 }
386 mp3DecInfo->mainDataBegin = si->mainDataBegin; /* needed by main decode loop */
387
388 ASSERT(nBytes == CalcBitsUsed(bsi, buf, 0) >> 3);
389
390 return nBytes;
391}
392
StereoMode
Definition coder.h:121
@ Mono
Definition coder.h:125
@ Joint
Definition coder.h:123
#define SIBYTES_MPEG2_MONO
Definition coder.h:76
#define SIBYTES_MPEG1_MONO
Definition coder.h:74
#define CalcBitsUsed
Definition coder.h:95
#define GetBits
Definition coder.h:94
#define SIBYTES_MPEG2_STEREO
Definition coder.h:77
#define SIBYTES_MPEG1_STEREO
Definition coder.h:75
#define SetBitstreamPointer
Definition coder.h:93
#define ASSERT(x)
Definition coder.h:55
#define NGRANS_MPEG2
Definition mp3common.h:52
#define MAX_SCFBD
Definition mp3common.h:50
#define SYNCWORDL
Definition mp3common.h:62
#define SYNCWORDH
Definition mp3common.h:61
#define NGRANS_MPEG1
Definition mp3common.h:51
MPEGVersion
Definition mp3dec.h:83
@ MPEG25
Definition mp3dec.h:86
@ MPEG2
Definition mp3dec.h:85
@ MPEG1
Definition mp3dec.h:84
#define sfBandTable
Definition statname.h:80
#define samplerateTab
Definition statname.h:74
#define sideBytesTab
Definition statname.h:78
#define UnpackSideInfo
Definition statname.h:65
#define slotTab
Definition statname.h:79
#define bitrateTab
Definition statname.h:75
#define samplesPerFrameTab
Definition statname.h:76
#define UnpackFrameHeader
Definition statname.h:64
#define CheckPadBit
Definition statname.h:63
unsigned char * bytePtr
Definition coder.h:129
int cachedBits
Definition coder.h:131
unsigned int iCache
Definition coder.h:130
const SFBandTable * sfBand
Definition coder.h:150
int brIdx
Definition coder.h:139
int srIdx
Definition coder.h:140
int CRCWord
Definition coder.h:148
int emphasis
Definition coder.h:147
int copyFlag
Definition coder.h:145
MPEGVersion ver
Definition coder.h:136
int origFlag
Definition coder.h:146
int paddingBit
Definition coder.h:141
int modeExt
Definition coder.h:144
StereoMode sMode
Definition coder.h:143
int privateBit
Definition coder.h:142
int layer
Definition coder.h:137
MPEGVersion version
Definition mp3common.h:89
int mainDataBegin
Definition mp3common.h:91
void * FrameHeaderPS
Definition mp3common.h:66
void * SideInfoPS
Definition mp3common.h:67
int nGranSamps
Definition mp3common.h:86
int scfsi[MAX_NCHAN][MAX_SCFBD]
Definition coder.h:173
int privateBits
Definition coder.h:172
SideInfoSub sis[MAX_NGRAN][MAX_NCHAN]
Definition coder.h:175
int mainDataBegin
Definition coder.h:171
int preFlag
Definition coder.h:165
int sfactScale
Definition coder.h:166
int mixedBlock
Definition coder.h:160
int nBigvals
Definition coder.h:155
int part23Length
Definition coder.h:154
int count1TableSelect
Definition coder.h:167
int winSwitchFlag
Definition coder.h:158
int sfCompress
Definition coder.h:157
int tableSelect[3]
Definition coder.h:161
int region1Count
Definition coder.h:164
int region0Count
Definition coder.h:163
int subBlockGain[3]
Definition coder.h:162
int blockType
Definition coder.h:159
int globalGain
Definition coder.h:156