1/**
2 *
3 * File Name:  omxVCM4P2_DecodeBlockCoef_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 for intra reconstruction
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 * Function:  omxVCM4P2_DecodeBlockCoef_Intra   (6.2.5.4.1)
26 *
27 * Description:
28 * Decodes the INTRA block coefficients. Inverse quantization, inversely
29 * zigzag positioning, and IDCT, with appropriate clipping on each step, are
30 * performed on the coefficients. The results are then placed in the output
31 * frame/plane on a pixel basis.  Note: This function will be used only when
32 * at least one non-zero AC coefficient of current block exists in the bit
33 * stream. The DC only condition will be handled in another function.
34 *
35 *
36 * Input Arguments:
37 *
38 *   ppBitStream - pointer to the pointer to the current byte in the bit
39 *            stream buffer. There is no boundary check for the bit stream
40 *            buffer.
41 *   pBitOffset - pointer to the bit position in the byte pointed to by
42 *            *ppBitStream. *pBitOffset is valid within [0-7].
43 *   step - width of the destination plane
44 *   pCoefBufRow - pointer to the coefficient row buffer; must be aligned on
45 *            an 8-byte boundary.
46 *   pCoefBufCol - pointer to the coefficient column buffer; must be aligned
47 *            on an 8-byte boundary.
48 *   curQP - quantization parameter of the macroblock which the current block
49 *            belongs to
50 *   pQPBuf - pointer to the quantization parameter buffer
51 *   blockIndex - block index indicating the component type and position as
52 *            defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5.
53 *   intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a
54 *            mechanism to switch between two VLC for coding of Intra DC
55 *            coefficients as per [ISO14496-2], Table 6-21.
56 *   ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if
57 *            the ac coefficients of the first row or first column are
58 *            differentially coded for intra coded macroblock.
59 *   shortVideoHeader - binary flag indicating presence of
60 *            short_video_header; shortVideoHeader==1 selects linear intra DC
61 *            mode, and shortVideoHeader==0 selects non linear intra DC mode.
62 *
63 * Output Arguments:
64 *
65 *   ppBitStream - *ppBitStream is updated after the block is decoded, so
66 *            that it points to the current byte in the bit stream buffer
67 *   pBitOffset - *pBitOffset is updated so that it points to the current bit
68 *            position in the byte pointed by *ppBitStream
69 *   pDst - pointer to the block in the destination plane; must be aligned on
70 *            an 8-byte boundary.
71 *   pCoefBufRow - pointer to the updated coefficient row buffer.
72 *   pCoefBufCol - pointer to the updated coefficient column buffer  Note:
73 *            The coefficient buffers must be updated in accordance with the
74 *            update procedure defined in section 6.2.2.
75 *
76 * Return Value:
77 *
78 *    OMX_Sts_NoErr - no error
79 *    OMX_Sts_BadArgErr - bad arguments, if:
80 *    -    At least one of the following pointers is NULL:
81 *         ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol,
82 *         pQPBuf, pDst.
83 *    -    *pBitOffset exceeds [0,7]
84 *    -    curQP exceeds (1, 31)
85 *    -    blockIndex exceeds [0,5]
86 *    -    step is not the multiple of 8
87 *    -    a pointer alignment requirement was violated.
88 *    OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra.
89 *
90 */
91
92OMXResult omxVCM4P2_DecodeBlockCoef_Intra(
93     const OMX_U8 ** ppBitStream,
94     OMX_INT *pBitOffset,
95     OMX_U8 *pDst,
96     OMX_INT step,
97     OMX_S16 *pCoefBufRow,
98     OMX_S16 *pCoefBufCol,
99     OMX_U8 curQP,
100     const OMX_U8 *pQPBuf,
101     OMX_INT blockIndex,
102     OMX_INT intraDCVLC,
103     OMX_INT ACPredFlag,
104	 OMX_INT shortVideoHeader
105 )
106{
107    OMX_S16 tempBuf1[79], tempBuf2[79];
108    OMX_S16 *pTempBuf1, *pTempBuf2;
109    OMX_INT predDir, predACDir, i, j, count;
110    OMX_INT  predQP;
111    OMXVCM4P2VideoComponent videoComp;
112    OMXResult errorCode;
113
114    /* Argument error checks */
115    armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
116    armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
117    armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
118    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
119    armRetArgErrIf(pCoefBufRow == NULL, OMX_Sts_BadArgErr);
120    armRetArgErrIf(pCoefBufCol == NULL, OMX_Sts_BadArgErr);
121    armRetArgErrIf(pQPBuf == NULL, OMX_Sts_BadArgErr);
122    armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
123    armRetArgErrIf(((curQP <= 0) || (curQP >= 32)), OMX_Sts_BadArgErr);
124    armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
125    armRetArgErrIf((blockIndex < 0) || (blockIndex > 5), OMX_Sts_BadArgErr);
126    armRetArgErrIf((step % 8) != 0, OMX_Sts_BadArgErr);
127
128
129    /* Aligning the local buffers */
130    pTempBuf1 = armAlignTo16Bytes(tempBuf1);
131    pTempBuf2 = armAlignTo16Bytes(tempBuf2);
132
133    /* Setting the AC prediction direction and prediction direction */
134    armVCM4P2_SetPredDir(
135        blockIndex,
136        pCoefBufRow,
137        pCoefBufCol,
138        &predDir,
139        &predQP,
140        pQPBuf);
141
142    predACDir = predDir;
143
144    armRetArgErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr);
145
146    if (ACPredFlag == 0)
147    {
148        predACDir = OMX_VC_NONE;
149    }
150
151    /* Setting the videoComp */
152    if (blockIndex <= 3)
153    {
154        videoComp = OMX_VC_LUMINANCE;
155    }
156    else
157    {
158        videoComp = OMX_VC_CHROMINANCE;
159    }
160
161
162    /* VLD and zigzag */
163    if (intraDCVLC == 1)
164    {
165        errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
166            ppBitStream,
167            pBitOffset,
168            pTempBuf1,
169            predACDir,
170            shortVideoHeader,
171            videoComp);
172        armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
173    }
174    else
175    {
176        errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
177            ppBitStream,
178            pBitOffset,
179            pTempBuf1,
180            predACDir,
181            shortVideoHeader);
182        armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
183    }
184
185    /* AC DC prediction */
186    errorCode = omxVCM4P2_PredictReconCoefIntra(
187        pTempBuf1,
188        pCoefBufRow,
189        pCoefBufCol,
190        curQP,
191        predQP,
192        predDir,
193        ACPredFlag,
194        videoComp);
195    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
196
197    /* Dequantization */
198    errorCode = omxVCM4P2_QuantInvIntra_I(
199     pTempBuf1,
200     curQP,
201     videoComp,
202     shortVideoHeader);
203    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
204
205    /* Inverse transform */
206    errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2);
207    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
208
209    /* Placing the linear array into the destination plane and clipping
210       it to 0 to 255 */
211    for (j = 0, count = 0; j < 8; j++)
212    {
213        for(i = 0; i < 8; i++, count++)
214        {
215            pDst[i] = armClip (0, 255, pTempBuf2[count]);
216        }
217        pDst += step;
218    }
219
220    return OMX_Sts_NoErr;
221}
222
223/* End of file */
224
225
226