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