armVCM4P2_ACDCPredict.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/**
2 *
3 * File Name:  armVCM4P2_ACDCPredict.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 DC/AC coefficient prediction
14 *
15 */
16
17#include "omxtypes.h"
18#include "armOMX.h"
19
20#include "armVC.h"
21#include "armCOMM.h"
22
23/**
24 * Function: armVCM4P2_ACDCPredict
25 *
26 * Description:
27 * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
28 * to the function call, prediction direction (predDir) should be selected
29 * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
30 *
31 * Remarks:
32 *
33 * Parameters:
34 * [in] pSrcDst     pointer to the coefficient buffer which contains
35 *                          the quantized coefficient residuals (PQF) of the
36 *                          current block
37 * [in] pPredBufRow pointer to the coefficient row buffer
38 * [in] pPredBufCol pointer to the coefficient column buffer
39 * [in] curQP       quantization parameter of the current block. curQP
40 *                          may equal to predQP especially when the current
41 *                          block and the predictor block are in the same
42 *                          macroblock.
43 * [in] predQP      quantization parameter of the predictor block
44 * [in] predDir     indicates the prediction direction which takes one
45 *                          of the following values:
46 *                          OMX_VC_HORIZONTAL    predict horizontally
47 *                          OMX_VC_VERTICAL      predict vertically
48 * [in] ACPredFlag  a flag indicating if AC prediction should be
49 *                          performed. It is equal to ac_pred_flag in the bit
50 *                          stream syntax of MPEG-4
51 * [in] videoComp   video component type (luminance, chrominance or
52 *                          alpha) of the current block
53 * [in] flag        This flag defines the if one wants to use this functions to
54 *                  calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
55 * [out]    pPreACPredict   pointer to the predicted coefficients buffer.
56 *                          Filled ONLY if it is not NULL
57 * [out]    pSrcDst     pointer to the coefficient buffer which contains
58 *                          the quantized coefficients (QF) of the current
59 *                          block
60 * [out]    pPredBufRow pointer to the updated coefficient row buffer
61 * [out]    pPredBufCol pointer to the updated coefficient column buffer
62 * [out]    pSumErr     pointer to the updated sum of the difference
63 *                      between predicted and unpredicted coefficients
64 *                      If this is NULL, do not update
65 *
66 * Return Value:
67 * Standard OMXResult result. See enumeration for possible result codes.
68 *
69 */
70
71OMXResult armVCM4P2_ACDCPredict(
72     OMX_S16 * pSrcDst,
73     OMX_S16 * pPreACPredict,
74     OMX_S16 * pPredBufRow,
75     OMX_S16 * pPredBufCol,
76     OMX_INT curQP,
77     OMX_INT predQP,
78     OMX_INT predDir,
79     OMX_INT ACPredFlag,
80     OMXVCM4P2VideoComponent videoComp,
81     OMX_U8 flag,
82     OMX_INT *pSumErr
83)
84{
85    OMX_INT dcScaler, i;
86    OMX_S16 tempPred;
87
88    /* Argument error checks */
89    armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
90    armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
91    armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
92    armRetArgErrIf(curQP <= 0, OMX_Sts_BadArgErr);
93    armRetArgErrIf(predQP <= 0, OMX_Sts_BadArgErr);
94    armRetArgErrIf((predDir != 1) && (predDir != 2), OMX_Sts_BadArgErr);
95    armRetArgErrIf(!armIs4ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
96    armRetArgErrIf(!armIs4ByteAligned(pPredBufRow), OMX_Sts_BadArgErr);
97    armRetArgErrIf(!armIs4ByteAligned(pPredBufCol), OMX_Sts_BadArgErr);
98
99
100    /* Set DC scaler value to avoid some compilers giving a warning. */
101    dcScaler=0;
102
103    /* Calculate the DC scaler value */
104    if (videoComp == OMX_VC_LUMINANCE)
105    {
106        if (curQP >= 1 && curQP <= 4)
107        {
108            dcScaler = 8;
109        }
110        else if (curQP >= 5 && curQP <= 8)
111        {
112            dcScaler = 2 * curQP;
113        }
114        else if (curQP >= 9 && curQP <= 24)
115        {
116            dcScaler = curQP + 8;
117        }
118        else
119        {
120            dcScaler = (2 * curQP) - 16;
121        }
122    }
123    else if (videoComp == OMX_VC_CHROMINANCE)
124    {
125        if (curQP >= 1 && curQP <= 4)
126        {
127            dcScaler = 8;
128        }
129        else if (curQP >= 5 && curQP <= 24)
130        {
131            dcScaler = (curQP + 13)/2;
132        }
133        else
134        {
135            dcScaler = curQP - 6;
136        }
137    }
138
139    if (pPreACPredict != NULL)
140    {
141        pPreACPredict[0] = predDir;
142    }
143
144    if (predDir == OMX_VC_VERTICAL)
145    {
146        /* F[0][0]//dc_scaler */
147        tempPred = armIntDivAwayFromZero(pPredBufRow[0], dcScaler);
148    }
149    else
150    {
151        /* F[0][0]//dc_scaler */
152        tempPred = armIntDivAwayFromZero(pPredBufCol[0], dcScaler);
153    }
154
155    /* Updating the DC value to the row and col buffer */
156    *(pPredBufRow - 8) = *pPredBufCol;
157
158    if (flag)
159    {
160        /* Cal and store F[0][0] into the col buffer */
161        *pPredBufCol = pSrcDst[0] * dcScaler;
162
163        /* PQF = QF - F[0][0]//dc_scaler */
164        pSrcDst[0] -= tempPred;
165    }
166    else
167    {
168        /* QF = PQF + F[0][0]//dc_scaler */
169        pSrcDst[0] += tempPred;
170
171        /* Saturate */
172        pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]);
173
174        /* Cal and store F[0][0] into the col buffer */
175        *pPredBufCol = pSrcDst[0] * dcScaler;
176    }
177
178
179    if (ACPredFlag == 1)
180    {
181        if (predDir == OMX_VC_VERTICAL)
182        {
183            for (i = 1; i < 8; i++)
184            {
185                tempPred = armIntDivAwayFromZero \
186                              (pPredBufRow[i] * predQP, curQP);
187                if (flag)
188                {
189                    /* Updating QF to the row buff */
190                    pPredBufRow[i] = pSrcDst[i];
191                    /*PQFX[v][0] = QFX[v][0] - (QFA[v][0] * QPA) // QPX */
192                    pSrcDst[i] -= tempPred;
193                    /* Sum of absolute values of AC prediction error, this can
194                    be used as a reference to choose whether to use
195                    AC prediction */
196                    *pSumErr += armAbs(pSrcDst[i]);
197                    /* pPreACPredict[1~7] store the error signal
198                    after AC prediction */
199                    pPreACPredict[i] = pSrcDst[i];
200                }
201                else
202                {
203                    /*QFX[v][0] = PQFX[v][0] + (QFA[v][0] * QPA) // QPX */
204                    pSrcDst[i] += tempPred;
205
206                    /* Saturate */
207                    pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
208
209                    /* Updating QF to the row buff */
210                    pPredBufRow[i] = pSrcDst[i];
211                }
212            }
213        }
214        else
215        {
216            for (i = 8; i < 64; i += 8)
217            {
218                tempPred = armIntDivAwayFromZero \
219                              (pPredBufCol[i>>3] * predQP, curQP);
220                if (flag)
221                {
222                    /* Updating QF to col buff */
223                    pPredBufCol[i>>3] = pSrcDst[i];
224                    /*PQFX[0][u] = QFX[0][u] - (QFA[0][u] * QPA) // QPX */
225                    pSrcDst[i] -= tempPred;
226                    /* Sum of absolute values of AC prediction error, this can
227                    be used as a reference to choose whether to use AC
228                    prediction */
229                    *pSumErr += armAbs(pSrcDst[i]);
230                    /* pPreACPredict[1~7] store the error signal
231                    after AC prediction */
232                    pPreACPredict[i>>3] = pSrcDst[i];
233                }
234                else
235                {
236                    /*QFX[0][u] = PQFX[0][u] + (QFA[0][u] * QPA) // QPX */
237                    pSrcDst[i] += tempPred;
238
239                    /* Saturate */
240                    pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
241
242                    /* Updating QF to col buff */
243                    pPredBufCol[i>>3] = pSrcDst[i];
244                }
245            }
246        }
247    }
248
249    return OMX_Sts_NoErr;
250}
251
252/*End of File*/
253
254