omxVCM4P10_GetVLCInfo.c revision 78e52bfac041d71ce53b5b13c2abf78af742b09d
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:  omxVCM4P10_GetVLCInfo.c
20 * OpenMAX DL: v1.0.2
21 * Revision:   9641
22 * Date:       Thursday, February 7, 2008
23 *
24 *
25 *
26 * Description:
27 *
28 * This function extracts run-length encoding (RLE) information
29 */
30
31#include "omxtypes.h"
32#include "armOMX.h"
33#include "omxVC.h"
34
35#include "armCOMM.h"
36#include "armVC.h"
37
38/**
39 * Function:  omxVCM4P10_GetVLCInfo   (6.3.5.9.1)
40 *
41 * Description:
42 * This function extracts run-length encoding (RLE) information from the
43 * coefficient matrix.  The results are returned in an OMXVCM4P10VLCInfo
44 * structure.
45 *
46 * Input Arguments:
47 *
48 *   pSrcCoeff - pointer to the transform coefficient matrix.  8-byte
49 *            alignment required.
50 *   pScanMatrix - pointer to the scan order definition matrix.  For a luma
51 *            block the scan matrix should follow [ISO14496-10] section 8.5.4,
52 *            and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
53 *            10, 7, 11, 14, 15.  For a chroma block, the scan matrix should
54 *            contain the values 0, 1, 2, 3.
55 *   bAC - indicates presence of a DC coefficient; 0 = DC coefficient
56 *            present, 1= DC coefficient absent.
57 *   MaxNumCoef - specifies the number of coefficients contained in the
58 *            transform coefficient matrix, pSrcCoeff. The value should be 16
59 *            for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
60 *            value should be 4 for blocks of type CHROMADC.
61 *
62 * Output Arguments:
63 *
64 *   pDstVLCInfo - pointer to structure that stores information for
65 *            run-length coding.
66 *
67 * Return Value:
68 *
69 *    OMX_Sts_NoErr - no error
70 *    OMX_Sts_BadArgErr - bad arguments; returned if any of the following
71 *              conditions are true:
72 *    -    at least one of the following pointers is NULL:
73 *            pSrcCoeff, pScanMatrix, pDstVLCInfo
74 *    -    pSrcCoeff is not aligned on an 8-byte boundary
75 *
76 */
77OMXResult omxVCM4P10_GetVLCInfo (
78	const OMX_S16*		    pSrcCoeff,
79	const OMX_U8*			    pScanMatrix,
80	OMX_U8			    bAC,
81	OMX_U32			    MaxNumCoef,
82	OMXVCM4P10VLCInfo*	pDstVLCInfo
83)
84{
85    OMX_INT     i, MinIndex;
86    OMX_S32     Value;
87    OMX_U32     Mask = 4, RunBefore;
88    OMX_S16     *pLevel;
89    OMX_U8      *pRun;
90    OMX_S16     Buf [16];
91
92    /* check for argument error */
93    armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr)
94    armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr)
95    armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr)
96    armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr)
97    armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr)
98    armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr)
99
100    /* Initialize RLE Info structure */
101    pDstVLCInfo->uTrailing_Ones = 0;
102    pDstVLCInfo->uTrailing_One_Signs = 0;
103    pDstVLCInfo->uNumCoeffs = 0;
104    pDstVLCInfo->uTotalZeros = 0;
105
106    for (i = 0; i < 16; i++)
107    {
108        pDstVLCInfo->iLevels [i] = 0;
109        pDstVLCInfo->uRuns [i] = 0;
110    }
111
112    MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0;
113    for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++)
114    {
115        /* Scan */
116        Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]];
117    }
118
119    /* skip zeros at the end */
120    i = MaxNumCoef - 1;
121    while (!Buf [i] && i >= 0)
122    {
123        i--;
124    }
125
126    if (i < 0)
127    {
128        return OMX_Sts_NoErr;
129    }
130
131    /* Fill RLE Info structure */
132    pLevel = pDstVLCInfo->iLevels;
133    pRun = pDstVLCInfo->uRuns;
134    RunBefore = 0;
135
136    /* Handle first non zero separate */
137    pDstVLCInfo->uNumCoeffs++;
138    Value = Buf [i];
139    if (Value == 1 || Value == -1)
140    {
141        pDstVLCInfo->uTrailing_Ones++;
142
143        pDstVLCInfo->uTrailing_One_Signs |=
144            Value == -1 ? Mask : 0;
145        Mask >>= 1;
146    }
147    else
148    {
149        Value -= (Value > 0 ? 1 : -1);
150        *pLevel++ = Value;
151        Mask = 0;
152    }
153
154    /* Remaining non zero */
155    while (--i >= 0)
156    {
157        Value = Buf [i];
158        if (Value)
159        {
160            pDstVLCInfo->uNumCoeffs++;
161
162            /* Mask becomes zero after entering */
163            if (Mask &&
164                (Value == 1 ||
165                 Value == -1))
166            {
167                pDstVLCInfo->uTrailing_Ones++;
168
169                pDstVLCInfo->uTrailing_One_Signs |=
170                    Value == -1 ? Mask : 0;
171                Mask >>= 1;
172                *pRun++ = RunBefore;
173                RunBefore = 0;
174            }
175            else
176            {
177                /* If 3 trailing ones are not completed */
178                if (Mask)
179                {
180                    Mask = 0;
181                    Value -= (Value > 0 ? 1 : -1);
182                }
183                *pLevel++ = Value;
184                *pRun++ = RunBefore;
185                RunBefore = 0;
186            }
187        }
188        else
189        {
190            pDstVLCInfo->uTotalZeros++;
191            RunBefore++;
192        }
193    }
194
195    /* Update last run */
196    if (RunBefore)
197    {
198        *pRun++ = RunBefore;
199    }
200
201    return OMX_Sts_NoErr;
202}
203
204/*****************************************************************************
205 *                              END OF FILE
206 *****************************************************************************/
207
208