armVCM4P10_DecodeCoeffsToPair.c revision 78e52bfac041d71ce53b5b13c2abf78af742b09d
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 * 20 * File Name: armVCM4P10_DecodeCoeffsToPair.c 21 * OpenMAX DL: v1.0.2 22 * Revision: 9641 23 * Date: Thursday, February 7, 2008 24 * 25 * 26 * 27 * 28 * H.264 decode coefficients module 29 * 30 */ 31 32#ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR 33#undef DEBUG_ON 34#define DEBUG_ON 35#endif 36 37#include "omxtypes.h" 38#include "armOMX.h" 39#include "omxVC.h" 40 41#include "armCOMM.h" 42#include "armCOMM_Bitstream.h" 43#include "armVCM4P10_CAVLCTables.h" 44 45/* 4x4 DeZigZag table */ 46 47static const OMX_U8 armVCM4P10_ZigZag[16] = 48{ 49 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 50}; 51 52/* 53 * Description: 54 * This function perform the work required by the OpenMAX 55 * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair. 56 * Since most of the code is common we share it here. 57 * 58 * Parameters: 59 * [in] ppBitStream Double pointer to current byte in bit stream buffer 60 * [in] pOffset Pointer to current bit position in the byte pointed 61 * to by *ppBitStream 62 * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current 63 * block (4,15 or 16) 64 * [in] nTable Table number (0 to 4) according to the five columns 65 * of Table 9-5 in the H.264 spec 66 * [out] ppBitStream *ppBitStream is updated after each block is decoded 67 * [out] pOffset *pOffset is updated after each block is decoded 68 * [out] pNumCoeff Pointer to the number of nonzero coefficients in 69 * this block 70 * [out] ppPosCoefbuf Double pointer to destination residual 71 * coefficient-position pair buffer 72 * Return Value: 73 * Standard omxError result. See enumeration for possible result codes. 74 75 */ 76 77OMXResult armVCM4P10_DecodeCoeffsToPair( 78 const OMX_U8** ppBitStream, 79 OMX_S32* pOffset, 80 OMX_U8* pNumCoeff, 81 OMX_U8 **ppPosCoefbuf, 82 OMX_INT nTable, 83 OMX_INT sMaxNumCoeff 84 ) 85{ 86 int CoeffToken, TotalCoeff, TrailingOnes; 87 int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize; 88 int SuffixLength, Run, ZerosLeft,CoeffNum; 89 int i, Flags; 90 OMX_U8 *pPosCoefbuf = *ppPosCoefbuf; 91 OMX_S16 pLevel[16]; 92 OMX_U8 pRun[16]; 93 94 CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]); 95 armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); 96 97 TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken]; 98 TotalCoeff = armVCM4P10_CAVLCTotalCoeff[CoeffToken]; 99 *pNumCoeff = (OMX_U8)TotalCoeff; 100 101 DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes); 102 103 if (TotalCoeff == 0) 104 { 105 /* Nothing to do */ 106 return OMX_Sts_NoErr; 107 } 108 109 /* Decode trailing ones */ 110 for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--) 111 { 112 if (armGetBits(ppBitStream, pOffset, 1)) 113 { 114 Level = -1; 115 } 116 else 117 { 118 Level = +1; 119 } 120 pLevel[i] = (OMX_S16)Level; 121 122 DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); 123 } 124 125 /* Decode (non zero) level values */ 126 SuffixLength = 0; 127 if (TotalCoeff>10 && TrailingOnes<3) 128 { 129 SuffixLength=1; 130 } 131 for ( ; i>=0; i--) 132 { 133 LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix); 134 armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); 135 136 LevelSuffixSize = SuffixLength; 137 if (LevelPrefix==14 && SuffixLength==0) 138 { 139 LevelSuffixSize = 4; 140 } 141 if (LevelPrefix==15) 142 { 143 LevelSuffixSize = 12; 144 } 145 146 LevelSuffix = 0; 147 if (LevelSuffixSize > 0) 148 { 149 LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize); 150 } 151 152 LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix; 153 154 155 if (LevelPrefix==15 && SuffixLength==0) 156 { 157 LevelCode += 15; 158 } 159 160 /* LevelCode = 2*(magnitude-1) + sign */ 161 162 if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3) 163 { 164 /* Level magnitude can't be 1 */ 165 LevelCode += 2; 166 } 167 if (LevelCode & 1) 168 { 169 /* 2a+1 maps to -a-1 */ 170 Level = (-LevelCode-1)>>1; 171 } 172 else 173 { 174 /* 2a+0 maps to +a+1 */ 175 Level = (LevelCode+2)>>1; 176 } 177 pLevel[i] = (OMX_S16)Level; 178 179 DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); 180 181 if (SuffixLength==0) 182 { 183 SuffixLength=1; 184 } 185 if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 ) 186 { 187 SuffixLength++; 188 } 189 } 190 191 /* Decode run values */ 192 ZerosLeft = 0; 193 if (TotalCoeff < sMaxNumCoeff) 194 { 195 /* Decode TotalZeros VLC */ 196 if (sMaxNumCoeff==4) 197 { 198 ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]); 199 armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); 200 } 201 else 202 { 203 ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]); 204 armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); 205 } 206 } 207 208 DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft); 209 210 CoeffNum=ZerosLeft+TotalCoeff-1; 211 212 for (i=TotalCoeff-1; i>0; i--) 213 { 214 Run = 0; 215 if (ZerosLeft > 0) 216 { 217 int Table = ZerosLeft; 218 if (Table > 6) 219 { 220 Table = 7; 221 } 222 Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]); 223 armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); 224 } 225 pRun[i] = (OMX_U8)Run; 226 227 DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]); 228 229 ZerosLeft -= Run; 230 } 231 pRun[0] = (OMX_U8)ZerosLeft; 232 233 DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]); 234 235 236 /* Fill in coefficients */ 237 238 if (sMaxNumCoeff==15) 239 { 240 CoeffNum++; /* Skip the DC position */ 241 } 242 243 /*for (i=0;i<TotalCoeff;i++) 244 CoeffNum += pRun[i]+1;*/ 245 246 for (i=(TotalCoeff-1); i>=0; i--) 247 { 248 /*CoeffNum += pRun[i]+1;*/ 249 Level = pLevel[i]; 250 251 DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level); 252 253 Flags = CoeffNum; 254 CoeffNum -= (pRun[i]+1); 255 if (sMaxNumCoeff>4) 256 { 257 /* Perform 4x4 DeZigZag */ 258 Flags = armVCM4P10_ZigZag[Flags]; 259 } 260 if (i==0) 261 { 262 /* End of block flag */ 263 Flags += 0x20; 264 } 265 if (Level<-128 || Level>127) 266 { 267 /* Overflow flag */ 268 Flags += 0x10; 269 } 270 271 *pPosCoefbuf++ = (OMX_U8)(Flags); 272 *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF); 273 if (Flags & 0x10) 274 { 275 *pPosCoefbuf++ = (OMX_U8)(Level>>8); 276 } 277 } 278 279 *ppPosCoefbuf = pPosCoefbuf; 280 281 return OMX_Sts_NoErr; 282} 283