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 107 OMXResult 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