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