1/**
2 *
3 * File Name:  omxVCM4P2_TransRecBlockCoef_intra.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 modules DCT->quant and reconstructing the intra texture data
14 *
15 */
16
17#include "omxtypes.h"
18#include "armOMX.h"
19#include "omxVC.h"
20
21#include "armCOMM.h"
22#include "armVC.h"
23
24
25/**
26 * Function:  omxVCM4P2_TransRecBlockCoef_intra   (6.2.4.4.4)
27 *
28 * Description:
29 * Quantizes the DCT coefficients, implements intra block AC/DC coefficient
30 * prediction, and reconstructs the current intra block texture for prediction
31 * on the next frame.  Quantized row and column coefficients are returned in
32 * the updated coefficient buffers.
33 *
34 * Input Arguments:
35 *
36 *   pSrc - pointer to the pixels of current intra block; must be aligned on
37 *            an 8-byte boundary.
38 *   pPredBufRow - pointer to the coefficient row buffer containing
39 *            ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16.
40 *            Coefficients are organized into blocks of eight as described
41 *            below (Internal Prediction Coefficient Update Procedures).  The
42 *            DC coefficient is first, and the remaining buffer locations
43 *            contain the quantized AC coefficients. Each group of eight row
44 *            buffer elements combined with one element eight elements ahead
45 *            contains the coefficient predictors of the neighboring block
46 *            that is spatially above or to the left of the block currently to
47 *            be decoded. A negative-valued DC coefficient indicates that this
48 *            neighboring block is not INTRA-coded or out of bounds, and
49 *            therefore the AC and DC coefficients are invalid.  Pointer must
50 *            be aligned on an 8-byte boundary.
51 *   pPredBufCol - pointer to the prediction coefficient column buffer
52 *            containing 16 elements of type OMX_S16. Coefficients are
53 *            organized as described in section 6.2.2.5.  Pointer must be
54 *            aligned on an 8-byte boundary.
55 *   pSumErr - pointer to a flag indicating whether or not AC prediction is
56 *            required; AC prediction is enabled if *pSumErr >=0, but the
57 *            value is not used for coefficient prediction, i.e., the sum of
58 *            absolute differences starts from 0 for each call to this
59 *            function.  Otherwise AC prediction is disabled if *pSumErr < 0 .
60 *   blockIndex - block index indicating the component type and position, as
61 *            defined in [ISO14496-2], subclause 6.1.3.8.
62 *   curQp - quantization parameter of the macroblock to which the current
63 *            block belongs
64 *   pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0]
65 *            contains the quantization parameter associated with the 8x8
66 *            block left of the current block (QPa), and pQpBuf[1] contains
67 *            the quantization parameter associated with the 8x8 block above
68 *            the current block (QPc).  In the event that the corresponding
69 *            block is outside of the VOP bound, the Qp value will not affect
70 *            the intra prediction process, as described in [ISO14496-2],
71 *            sub-clause 7.4.3.3,  Adaptive AC Coefficient Prediction.
72 *   srcStep - width of the source buffer; must be a multiple of 8.
73 *   dstStep - width of the reconstructed destination buffer; must be a
74 *            multiple of 16.
75 *   shortVideoHeader - binary flag indicating presence of
76 *            short_video_header; shortVideoHeader==1 selects linear intra DC
77 *            mode, and shortVideoHeader==0 selects non linear intra DC mode.
78 *
79 * Output Arguments:
80 *
81 *   pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains
82 *            the predicted DC coefficient; the remaining entries contain the
83 *            quantized AC coefficients (without prediction).  The pointer
84 *            pDstmust be aligned on a 16-byte boundary.
85 *   pRec - pointer to the reconstructed texture; must be aligned on an
86 *            8-byte boundary.
87 *   pPredBufRow - pointer to the updated coefficient row buffer
88 *   pPredBufCol - pointer to the updated coefficient column buffer
89 *   pPreACPredict - if prediction is enabled, the parameter points to the
90 *            start of the buffer containing the coefficient differences for
91 *            VLC encoding. The entry pPreACPredict[0]indicates prediction
92 *            direction for the current block and takes one of the following
93 *            values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or
94 *            OMX_VC_VERTICAL.  The entries
95 *            pPreACPredict[1]-pPreACPredict[7]contain predicted AC
96 *            coefficients.  If prediction is disabled (*pSumErr<0) then the
97 *            contents of this buffer are undefined upon return from the
98 *            function
99 *   pSumErr - pointer to the value of the accumulated AC coefficient errors,
100 *            i.e., sum of the absolute differences between predicted and
101 *            unpredicted AC coefficients
102 *
103 * Return Value:
104 *
105 *    OMX_Sts_NoErr - no error
106 *    OMX_Sts_BadArgErr - Bad arguments:
107 *    -    At least one of the following pointers is NULL: pSrc, pDst, pRec,
108 *         pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr.
109 *    -    blockIndex < 0 or blockIndex >= 10;
110 *    -    curQP <= 0 or curQP >= 32.
111 *    -    srcStep, or dstStep <= 0 or not a multiple of 8.
112 *    -    pDst is not 16-byte aligned: .
113 *    -    At least one of the following pointers is not 8-byte aligned:
114 *         pSrc, pRec.
115 *
116 *  Note: The coefficient buffers must be updated in accordance with the
117 *        update procedures defined in section in 6.2.2.
118 *
119 */
120
121OMXResult omxVCM4P2_TransRecBlockCoef_intra(
122     const OMX_U8 *pSrc,
123     OMX_S16 * pDst,
124     OMX_U8 * pRec,
125     OMX_S16 *pPredBufRow,
126     OMX_S16 *pPredBufCol,
127     OMX_S16 * pPreACPredict,
128     OMX_INT *pSumErr,
129     OMX_INT blockIndex,
130     OMX_U8 curQp,
131     const OMX_U8 *pQpBuf,
132     OMX_INT srcStep,
133     OMX_INT dstStep,
134	 OMX_INT shortVideoHeader
135)
136{
137    /* 64 elements are needed but to align it to 16 bytes need
138    8 more elements of padding */
139    OMX_S16 tempBuf1[79], tempBuf2[79];
140    OMX_S16 tempBuf3[79];
141    OMX_S16 *pTempBuf1, *pTempBuf2,*pTempBuf3;
142    OMXVCM4P2VideoComponent videoComp;
143    OMX_U8  flag;
144    OMX_INT x, y, count, predDir;
145    OMX_INT predQP, ACPredFlag;
146
147
148    /* Aligning the local buffers */
149    pTempBuf1 = armAlignTo16Bytes(tempBuf1);
150    pTempBuf2 = armAlignTo16Bytes(tempBuf2);
151    pTempBuf3 = armAlignTo16Bytes(tempBuf3);
152
153    /* Argument error checks */
154    armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
155    armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr);
156    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
157    armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
158    armRetArgErrIf(!armIs8ByteAligned(pRec), OMX_Sts_BadArgErr);
159    armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
160    armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
161    armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
162    armRetArgErrIf(pPreACPredict == NULL, OMX_Sts_BadArgErr);
163    armRetArgErrIf(pSumErr == NULL, OMX_Sts_BadArgErr);
164    armRetArgErrIf(pQpBuf == NULL, OMX_Sts_BadArgErr);
165    armRetArgErrIf((srcStep <= 0) || (dstStep <= 0) ||
166                (dstStep & 7) || (srcStep & 7)
167                , OMX_Sts_BadArgErr);
168    armRetArgErrIf((blockIndex < 0) || (blockIndex > 9), OMX_Sts_BadArgErr);
169
170    armRetArgErrIf((curQp <= 0) || (curQp >=32), OMX_Sts_BadArgErr);
171
172
173   /* Setting the videoComp */
174    if (blockIndex <= 3)
175    {
176        videoComp = OMX_VC_LUMINANCE;
177    }
178    else
179    {
180        videoComp = OMX_VC_CHROMINANCE;
181    }
182    /* Converting from 2-d to 1-d buffer */
183    for (y = 0, count = 0; y < 8; y++)
184    {
185        for(x= 0; x < 8; x++, count++)
186        {
187            pTempBuf1[count] = pSrc[(y*srcStep) + x];
188        }
189    }
190
191    omxVCM4P2_DCT8x8blk  (pTempBuf1, pTempBuf2);
192    omxVCM4P2_QuantIntra_I(
193        pTempBuf2,
194        curQp,
195        blockIndex,
196        shortVideoHeader);
197
198    /* Converting from 1-D to 2-D buffer */
199    for (y = 0, count = 0; y < 8; y++)
200    {
201        for(x = 0; x < 8; x++, count++)
202        {
203            /* storing tempbuf2 to tempbuf1 */
204            pTempBuf1[count] = pTempBuf2[count];
205            pDst[(y*dstStep) + x] = pTempBuf2[count];
206        }
207    }
208
209    /* AC and DC prediction */
210    armVCM4P2_SetPredDir(
211        blockIndex,
212        pPredBufRow,
213        pPredBufCol,
214        &predDir,
215        &predQP,
216        pQpBuf);
217
218    armRetDataErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr);
219
220    flag = 1;
221    if (*pSumErr < 0)
222    {
223        ACPredFlag = 0;
224    }
225    else
226    {
227        ACPredFlag = 1;
228    }
229
230    armVCM4P2_ACDCPredict(
231        pTempBuf2,
232        pPreACPredict,
233        pPredBufRow,
234        pPredBufCol,
235        curQp,
236        predQP,
237        predDir,
238        ACPredFlag,
239        videoComp,
240        flag,
241        pSumErr);
242
243    /* Reconstructing the texture data */
244    omxVCM4P2_QuantInvIntra_I(
245        pTempBuf1,
246        curQp,
247        videoComp,
248        shortVideoHeader);
249    omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf3);
250    for(count = 0; count < 64; count++)
251    {
252        pRec[count] = armMax(0,pTempBuf3[count]);
253    }
254
255    return OMX_Sts_NoErr;
256}
257
258/* End of file */
259
260
261