summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c
blob: dd444f91b6eebdb9052d509a0e57bf746edcd020 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/**
 * 
 * File Name:  omxVCM4P2_TransRecBlockCoef_intra.c
 * OpenMAX DL: v1.0.2
 * Revision:   9641
 * Date:       Thursday, February 7, 2008
 * 
 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
 * 
 * 
 *
 * Description:
 * Contains modules DCT->quant and reconstructing the intra texture data
 * 
 */ 
 
#include "omxtypes.h"
#include "armOMX.h"
#include "omxVC.h"

#include "armCOMM.h"
#include "armVC.h"


/**
 * Function:  omxVCM4P2_TransRecBlockCoef_intra   (6.2.4.4.4)
 *
 * Description:
 * Quantizes the DCT coefficients, implements intra block AC/DC coefficient 
 * prediction, and reconstructs the current intra block texture for prediction 
 * on the next frame.  Quantized row and column coefficients are returned in 
 * the updated coefficient buffers. 
 *
 * Input Arguments:
 *   
 *   pSrc - pointer to the pixels of current intra block; must be aligned on 
 *            an 8-byte boundary. 
 *   pPredBufRow - pointer to the coefficient row buffer containing 
 *            ((num_mb_per_row * 2 + 1) * 8) elements of type OMX_S16. 
 *            Coefficients are organized into blocks of eight as described 
 *            below (Internal Prediction Coefficient Update Procedures).  The 
 *            DC coefficient is first, and the remaining buffer locations 
 *            contain the quantized AC coefficients. Each group of eight row 
 *            buffer elements combined with one element eight elements ahead 
 *            contains the coefficient predictors of the neighboring block 
 *            that is spatially above or to the left of the block currently to 
 *            be decoded. A negative-valued DC coefficient indicates that this 
 *            neighboring block is not INTRA-coded or out of bounds, and 
 *            therefore the AC and DC coefficients are invalid.  Pointer must 
 *            be aligned on an 8-byte boundary. 
 *   pPredBufCol - pointer to the prediction coefficient column buffer 
 *            containing 16 elements of type OMX_S16. Coefficients are 
 *            organized as described in section 6.2.2.5.  Pointer must be 
 *            aligned on an 8-byte boundary. 
 *   pSumErr - pointer to a flag indicating whether or not AC prediction is 
 *            required; AC prediction is enabled if *pSumErr >=0, but the 
 *            value is not used for coefficient prediction, i.e., the sum of 
 *            absolute differences starts from 0 for each call to this 
 *            function.  Otherwise AC prediction is disabled if *pSumErr < 0 . 
 *   blockIndex - block index indicating the component type and position, as 
 *            defined in [ISO14496-2], subclause 6.1.3.8. 
 *   curQp - quantization parameter of the macroblock to which the current 
 *            block belongs 
 *   pQpBuf - pointer to a 2-element quantization parameter buffer; pQpBuf[0] 
 *            contains the quantization parameter associated with the 8x8 
 *            block left of the current block (QPa), and pQpBuf[1] contains 
 *            the quantization parameter associated with the 8x8 block above 
 *            the current block (QPc).  In the event that the corresponding 
 *            block is outside of the VOP bound, the Qp value will not affect 
 *            the intra prediction process, as described in [ISO14496-2], 
 *            sub-clause 7.4.3.3,  Adaptive AC Coefficient Prediction.  
 *   srcStep - width of the source buffer; must be a multiple of 8. 
 *   dstStep - width of the reconstructed destination buffer; must be a 
 *            multiple of 16. 
 *   shortVideoHeader - binary flag indicating presence of 
 *            short_video_header; shortVideoHeader==1 selects linear intra DC 
 *            mode, and shortVideoHeader==0 selects non linear intra DC mode. 
 *
 * Output Arguments:
 *   
 *   pDst - pointer to the quantized DCT coefficient buffer; pDst[0] contains 
 *            the predicted DC coefficient; the remaining entries contain the 
 *            quantized AC coefficients (without prediction).  The pointer 
 *            pDstmust be aligned on a 16-byte boundary. 
 *   pRec - pointer to the reconstructed texture; must be aligned on an 
 *            8-byte boundary. 
 *   pPredBufRow - pointer to the updated coefficient row buffer 
 *   pPredBufCol - pointer to the updated coefficient column buffer 
 *   pPreACPredict - if prediction is enabled, the parameter points to the 
 *            start of the buffer containing the coefficient differences for 
 *            VLC encoding. The entry pPreACPredict[0]indicates prediction 
 *            direction for the current block and takes one of the following 
 *            values: OMX_VC_NONE (prediction disabled), OMX_VC_HORIZONTAL, or 
 *            OMX_VC_VERTICAL.  The entries 
 *            pPreACPredict[1]-pPreACPredict[7]contain predicted AC 
 *            coefficients.  If prediction is disabled (*pSumErr<0) then the 
 *            contents of this buffer are undefined upon return from the 
 *            function 
 *   pSumErr - pointer to the value of the accumulated AC coefficient errors, 
 *            i.e., sum of the absolute differences between predicted and 
 *            unpredicted AC coefficients 
 *
 * Return Value:
 *    
 *    OMX_Sts_NoErr - no error 
 *    OMX_Sts_BadArgErr - Bad arguments:
 *    -    At least one of the following pointers is NULL: pSrc, pDst, pRec, 
 *         pCoefBufRow, pCoefBufCol, pQpBuf, pPreACPredict, pSumErr. 
 *    -    blockIndex < 0 or blockIndex >= 10; 
 *    -    curQP <= 0 or curQP >= 32. 
 *    -    srcStep, or dstStep <= 0 or not a multiple of 8. 
 *    -    pDst is not 16-byte aligned: . 
 *    -    At least one of the following pointers is not 8-byte aligned: 
 *         pSrc, pRec.  
 *
 *  Note: The coefficient buffers must be updated in accordance with the 
 *        update procedures defined in section in 6.2.2. 
 *
 */

OMXResult omxVCM4P2_TransRecBlockCoef_intra(
     const OMX_U8 *pSrc,
     OMX_S16 * pDst,
     OMX_U8 * pRec,
     OMX_S16 *pPredBufRow,
     OMX_S16 *pPredBufCol,
     OMX_S16 * pPreACPredict,
     OMX_INT *pSumErr,
     OMX_INT blockIndex,
     OMX_U8 curQp,
     const OMX_U8 *pQpBuf,
     OMX_INT srcStep,
     OMX_INT dstStep,
	 OMX_INT shortVideoHeader
)
{
    /* 64 elements are needed but to align it to 16 bytes need
    8 more elements of padding */
    OMX_S16 tempBuf1[79], tempBuf2[79];
    OMX_S16 tempBuf3[79];
    OMX_S16 *pTempBuf1, *pTempBuf2,*pTempBuf3;
    OMXVCM4P2VideoComponent videoComp;
    OMX_U8  flag;
    OMX_INT x, y, count, predDir;
    OMX_INT predQP, ACPredFlag;
    

    /* Aligning the local buffers */
    pTempBuf1 = armAlignTo16Bytes(tempBuf1);
    pTempBuf2 = armAlignTo16Bytes(tempBuf2);
    pTempBuf3 = armAlignTo16Bytes(tempBuf3);

    /* Argument error checks */
    armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);
    armRetArgErrIf(!armIs8ByteAligned(pRec), OMX_Sts_BadArgErr);
    armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr);
    armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pPreACPredict == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pSumErr == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pQpBuf == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf((srcStep <= 0) || (dstStep <= 0) ||
                (dstStep & 7) || (srcStep & 7)
                , OMX_Sts_BadArgErr);
    armRetArgErrIf((blockIndex < 0) || (blockIndex > 9), OMX_Sts_BadArgErr);

    armRetArgErrIf((curQp <= 0) || (curQp >=32), OMX_Sts_BadArgErr);


   /* Setting the videoComp */
    if (blockIndex <= 3)
    {
        videoComp = OMX_VC_LUMINANCE;
    }
    else
    {
        videoComp = OMX_VC_CHROMINANCE;
    }
    /* Converting from 2-d to 1-d buffer */
    for (y = 0, count = 0; y < 8; y++)
    {
        for(x= 0; x < 8; x++, count++)
        {
            pTempBuf1[count] = pSrc[(y*srcStep) + x];
        }
    }

    omxVCM4P2_DCT8x8blk  (pTempBuf1, pTempBuf2);
    omxVCM4P2_QuantIntra_I(
        pTempBuf2,
        curQp,
        blockIndex,
        shortVideoHeader);

    /* Converting from 1-D to 2-D buffer */
    for (y = 0, count = 0; y < 8; y++)
    {
        for(x = 0; x < 8; x++, count++)
        {
            /* storing tempbuf2 to tempbuf1 */
            pTempBuf1[count] = pTempBuf2[count];
            pDst[(y*dstStep) + x] = pTempBuf2[count];
        }
    }

    /* AC and DC prediction */
    armVCM4P2_SetPredDir(
        blockIndex,
        pPredBufRow,
        pPredBufCol,
        &predDir,
        &predQP,
        pQpBuf);

    armRetDataErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr);

    flag = 1;
    if (*pSumErr < 0)
    {
        ACPredFlag = 0;
    }
    else
    {
        ACPredFlag = 1;
    }

    armVCM4P2_ACDCPredict(
        pTempBuf2,
        pPreACPredict,
        pPredBufRow,
        pPredBufCol,
        curQp,
        predQP,
        predDir,
        ACPredFlag,
        videoComp,
        flag,
        pSumErr);

    /* Reconstructing the texture data */
    omxVCM4P2_QuantInvIntra_I(
        pTempBuf1,
        curQp,
        videoComp,
        shortVideoHeader);
    omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf3);
    for(count = 0; count < 64; count++)
    {
        pRec[count] = armMax(0,pTempBuf3[count]);
    }

    return OMX_Sts_NoErr;
}

/* End of file */