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