1/**
2 *
3 * File Name:  armVCM4P2_GetVLCBits.c
4 * OpenMAX DL: v1.0.2
5 * Revision:   9641
6 * Date:       Thursday, February 7, 2008
7 *
8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
9 *
10 *
11 *
12 * Description:
13 * Contains module for VLC get bits from the stream
14 *
15 */
16
17#include "omxtypes.h"
18#include "armOMX.h"
19
20#include "armVC.h"
21#include "armCOMM.h"
22#include "armCOMM_Bitstream.h"
23#include "armVCM4P2_ZigZag_Tables.h"
24#include "armVCM4P2_Huff_Tables_VLC.h"
25
26
27/**
28 * Function: armVCM4P2_GetVLCBits
29 *
30 * Description:
31 * Performs escape mode decision based on the run, run+, level, level+ and
32 * last combinations.
33 *
34 * Remarks:
35 *
36 * Parameters:
37 * [in]	ppBitStream		pointer to the pointer to the current byte in
38 *								the bit stream
39 * [in]	pBitOffset		pointer to the bit position in the byte pointed
40 *								by *ppBitStream. Valid within 0 to 7
41 * [in] start           start indicates whether the encoding begins with
42 *                      0th element or 1st.
43 * [in/out] pLast       pointer to last status flag
44 * [in] runBeginSingleLevelEntriesL0      The run value from which level
45 *                                        will be equal to 1: last == 0
46 * [in] IndexBeginSingleLevelEntriesL0    Array index in the VLC table
47 *                                        pointing to the
48 *                                        runBeginSingleLevelEntriesL0
49 * [in] runBeginSingleLevelEntriesL1      The run value from which level
50 *                                        will be equal to 1: last == 1
51 * [in] IndexBeginSingleLevelEntriesL1    Array index in the VLC table
52 *                                        pointing to the
53 *                                        runBeginSingleLevelEntriesL0
54 * [in] pRunIndexTableL0    Run Index table defined in
55 *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
56 * [in] pVlcTableL0         VLC table for last == 0
57 * [in] pRunIndexTableL1    Run Index table defined in
58 *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
59 * [in] pVlcTableL1         VLC table for last == 1
60 * [in] pLMAXTableL0        Level MAX table defined in
61 *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
62 * [in] pLMAXTableL1        Level MAX table defined in
63 *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
64 * [in] pRMAXTableL0        Run MAX table defined in
65 *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
66 * [in] pRMAXTableL1        Run MAX table defined in
67 *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
68 * [out]pDst			    pointer to the coefficient buffer of current
69 *							block. Should be 32-bit aligned
70 *
71 * Return Value:
72 * Standard OMXResult result. See enumeration for possible result codes.
73 *
74 */
75
76OMXResult armVCM4P2_GetVLCBits (
77              const OMX_U8 **ppBitStream,
78              OMX_INT * pBitOffset,
79			  OMX_S16 * pDst,
80			  OMX_INT shortVideoHeader,
81			  OMX_U8    start,
82			  OMX_U8  * pLast,
83			  OMX_U8    runBeginSingleLevelEntriesL0,
84			  OMX_U8    maxIndexForMultipleEntriesL0,
85			  OMX_U8    maxRunForMultipleEntriesL1,
86			  OMX_U8    maxIndexForMultipleEntriesL1,
87              const OMX_U8  * pRunIndexTableL0,
88              const ARM_VLC32 *pVlcTableL0,
89			  const OMX_U8  * pRunIndexTableL1,
90              const ARM_VLC32 *pVlcTableL1,
91              const OMX_U8  * pLMAXTableL0,
92              const OMX_U8  * pLMAXTableL1,
93              const OMX_U8  * pRMAXTableL0,
94              const OMX_U8  * pRMAXTableL1,
95              const OMX_U8  * pZigzagTable
96)
97{
98    OMX_U32 storeRun;
99    OMX_U8  tabIndex, markerBit;
100    OMX_S16 storeLevel;
101    OMX_U16 unpackRetIndex;
102	OMX_U8  i, fType, escape;
103	OMX_U8  sign = 0;
104
105	/* Unpacking the bitstream and RLD */
106    for (i = start; i < 64;)
107    {
108		escape = armLookAheadBits(ppBitStream, pBitOffset, 7);
109		if (escape != 3)
110		{
111			fType = 0; /* Not in escape mode */
112		}
113		else
114		{
115			armSkipBits (ppBitStream, pBitOffset, 7);
116			if(shortVideoHeader)
117			{
118			  *pLast = armGetBits(ppBitStream, pBitOffset, 1);
119			  storeRun = armGetBits(ppBitStream, pBitOffset, 6);
120			  storeLevel = armGetBits(ppBitStream, pBitOffset, 8);
121
122			  /* Ref to Table B-18 (c) in MPEG4 Standard- FLC code for  */
123			  /* LEVEL when short_video_header is 1, the storeLevel is  */
124			  /* a signed value and the sign and the unsigned value for */
125			  /* storeLevel need to be extracted and passed to arm      */
126			  /* FillVLDBuffer function                                 */
127
128			  sign = (storeLevel & 0x80);
129			  if(sign==0x80)
130			  {
131			  	storeLevel=(storeLevel^0xff)+1;
132			  	sign=1;
133
134			  }
135
136			  armRetDataErrIf( storeLevel == 0 || sign*storeLevel == 128 , OMX_Sts_Err); /* Invalid FLC */
137			  armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
138			  armVCM4P2_FillVLDBuffer(
139			    storeRun,
140			    pDst,
141			    storeLevel,
142			    sign,
143			    *pLast,
144			    &i,
145			    pZigzagTable);
146			    return OMX_Sts_NoErr;
147
148			}
149			if (armGetBits(ppBitStream, pBitOffset, 1))
150			{
151				if (armGetBits(ppBitStream, pBitOffset, 1))
152				{
153					fType = 3;
154				}
155				else
156				{
157					fType = 2;
158				}
159			}
160			else
161			{
162				fType = 1;
163			}
164		}
165
166	    if (fType < 3)
167	    {
168	        unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
169										pVlcTableL0);
170			if (unpackRetIndex != ARM_NO_CODEBOOK_INDEX)
171		    {
172			    /* Decode run and level from the index */
173			    /* last = 0 */
174			    *pLast = 0;
175			    if (unpackRetIndex > maxIndexForMultipleEntriesL0)
176			    {
177				    storeLevel = 1;
178				    storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL0)
179							+ runBeginSingleLevelEntriesL0;
180			    }
181			    else
182			    {
183				    tabIndex = 1;
184				    while (pRunIndexTableL0[tabIndex] <= unpackRetIndex)
185				    {
186					    tabIndex++;
187				    }
188				    storeRun = tabIndex - 1;
189				    storeLevel = unpackRetIndex - pRunIndexTableL0[tabIndex - 1] + 1;
190			    }
191			    sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
192
193			    if (fType == 1)
194			    {
195				    storeLevel = (armAbs(storeLevel) + pLMAXTableL0[storeRun]);
196			    }
197			    else if (fType == 2)
198			    {
199				    storeRun = storeRun + pRMAXTableL0[storeLevel-1] + 1;
200			    }
201		    }
202		    else
203		    {
204			    unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
205											pVlcTableL1);
206
207			    armRetDataErrIf(unpackRetIndex == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
208
209			    /* Decode run and level from the index */
210			    /* last = 1 */
211			    *pLast = 1;
212			    if (unpackRetIndex > maxIndexForMultipleEntriesL1)
213			    {
214				    storeLevel = 1;
215				    storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL1)
216							+ maxRunForMultipleEntriesL1;
217		        }
218		        else
219			    {
220				    tabIndex = 1;
221				    while (pRunIndexTableL1[tabIndex] <= unpackRetIndex)
222				    {
223					    tabIndex++;
224				    }
225				    storeRun = tabIndex - 1;
226				    storeLevel = unpackRetIndex - pRunIndexTableL1[tabIndex - 1] + 1;
227			    }
228			    sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
229
230			    if (fType == 1)
231			    {
232			        storeLevel = (armAbs(storeLevel) + pLMAXTableL1[storeRun]);
233			    }
234			    else if (fType == 2)
235			    {
236				    storeRun = storeRun + pRMAXTableL1[storeLevel-1] + 1;
237			    }
238		    }
239            armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
240		    armVCM4P2_FillVLDBuffer(
241			    storeRun,
242			    pDst,
243			    storeLevel,
244			    sign,
245			    *pLast,
246			    &i,
247			    pZigzagTable);
248	    }
249	    else
250	    {
251		    *pLast = armGetBits(ppBitStream, pBitOffset, 1);
252		    storeRun  = armGetBits(ppBitStream, pBitOffset, 6);
253		    armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
254		    markerBit = armGetBits(ppBitStream, pBitOffset, 1);
255		    armRetDataErrIf( markerBit == 0, OMX_Sts_Err);
256		    storeLevel  = armGetBits(ppBitStream, pBitOffset, 12);
257		    if (storeLevel & 0x800)
258		    {
259			    storeLevel -= 4096;
260		    }
261		    armRetDataErrIf( storeLevel == 0 || storeLevel == -2048 , OMX_Sts_Err); /* Invalid FLC */
262		    armGetBits(ppBitStream, pBitOffset, 1);
263		    armVCM4P2_FillVLDBuffer(
264			    storeRun,
265			    pDst,
266			    storeLevel,
267			    0, /* Sign is not used, preprocessing done */
268			    *pLast,
269			    &i,
270			    pZigzagTable);
271
272	    }
273    } /* End of forloop for i */
274	return OMX_Sts_NoErr;
275}
276
277/* End of File */
278
279