1/** 2 * 3 * File Name: omxVCM4P10_GetVLCInfo.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 * Description: 12 * 13 * This function extracts run-length encoding (RLE) information 14 */ 15 16#include "omxtypes.h" 17#include "armOMX.h" 18#include "omxVC.h" 19 20#include "armCOMM.h" 21#include "armVC.h" 22 23/** 24 * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1) 25 * 26 * Description: 27 * This function extracts run-length encoding (RLE) information from the 28 * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo 29 * structure. 30 * 31 * Input Arguments: 32 * 33 * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte 34 * alignment required. 35 * pScanMatrix - pointer to the scan order definition matrix. For a luma 36 * block the scan matrix should follow [ISO14496-10] section 8.5.4, 37 * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 38 * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should 39 * contain the values 0, 1, 2, 3. 40 * bAC - indicates presence of a DC coefficient; 0 = DC coefficient 41 * present, 1= DC coefficient absent. 42 * MaxNumCoef - specifies the number of coefficients contained in the 43 * transform coefficient matrix, pSrcCoeff. The value should be 16 44 * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The 45 * value should be 4 for blocks of type CHROMADC. 46 * 47 * Output Arguments: 48 * 49 * pDstVLCInfo - pointer to structure that stores information for 50 * run-length coding. 51 * 52 * Return Value: 53 * 54 * OMX_Sts_NoErr - no error 55 * OMX_Sts_BadArgErr - bad arguments; returned if any of the following 56 * conditions are true: 57 * - at least one of the following pointers is NULL: 58 * pSrcCoeff, pScanMatrix, pDstVLCInfo 59 * - pSrcCoeff is not aligned on an 8-byte boundary 60 * 61 */ 62OMXResult omxVCM4P10_GetVLCInfo ( 63 const OMX_S16* pSrcCoeff, 64 const OMX_U8* pScanMatrix, 65 OMX_U8 bAC, 66 OMX_U32 MaxNumCoef, 67 OMXVCM4P10VLCInfo* pDstVLCInfo 68) 69{ 70 OMX_INT i, MinIndex; 71 OMX_S32 Value; 72 OMX_U32 Mask = 4, RunBefore; 73 OMX_S16 *pLevel; 74 OMX_U8 *pRun; 75 OMX_S16 Buf [16]; 76 77 /* check for argument error */ 78 armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr) 79 armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr) 80 armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr) 81 armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr) 82 armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr) 83 armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr) 84 85 /* Initialize RLE Info structure */ 86 pDstVLCInfo->uTrailing_Ones = 0; 87 pDstVLCInfo->uTrailing_One_Signs = 0; 88 pDstVLCInfo->uNumCoeffs = 0; 89 pDstVLCInfo->uTotalZeros = 0; 90 91 for (i = 0; i < 16; i++) 92 { 93 pDstVLCInfo->iLevels [i] = 0; 94 pDstVLCInfo->uRuns [i] = 0; 95 } 96 97 MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0; 98 for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++) 99 { 100 /* Scan */ 101 Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]]; 102 } 103 104 /* skip zeros at the end */ 105 i = MaxNumCoef - 1; 106 while (!Buf [i] && i >= 0) 107 { 108 i--; 109 } 110 111 if (i < 0) 112 { 113 return OMX_Sts_NoErr; 114 } 115 116 /* Fill RLE Info structure */ 117 pLevel = pDstVLCInfo->iLevels; 118 pRun = pDstVLCInfo->uRuns; 119 RunBefore = 0; 120 121 /* Handle first non zero separate */ 122 pDstVLCInfo->uNumCoeffs++; 123 Value = Buf [i]; 124 if (Value == 1 || Value == -1) 125 { 126 pDstVLCInfo->uTrailing_Ones++; 127 128 pDstVLCInfo->uTrailing_One_Signs |= 129 Value == -1 ? Mask : 0; 130 Mask >>= 1; 131 } 132 else 133 { 134 Value -= (Value > 0 ? 1 : -1); 135 *pLevel++ = Value; 136 Mask = 0; 137 } 138 139 /* Remaining non zero */ 140 while (--i >= 0) 141 { 142 Value = Buf [i]; 143 if (Value) 144 { 145 pDstVLCInfo->uNumCoeffs++; 146 147 /* Mask becomes zero after entering */ 148 if (Mask && 149 (Value == 1 || 150 Value == -1)) 151 { 152 pDstVLCInfo->uTrailing_Ones++; 153 154 pDstVLCInfo->uTrailing_One_Signs |= 155 Value == -1 ? Mask : 0; 156 Mask >>= 1; 157 *pRun++ = RunBefore; 158 RunBefore = 0; 159 } 160 else 161 { 162 /* If 3 trailing ones are not completed */ 163 if (Mask) 164 { 165 Mask = 0; 166 Value -= (Value > 0 ? 1 : -1); 167 } 168 *pLevel++ = Value; 169 *pRun++ = RunBefore; 170 RunBefore = 0; 171 } 172 } 173 else 174 { 175 pDstVLCInfo->uTotalZeros++; 176 RunBefore++; 177 } 178 } 179 180 /* Update last run */ 181 if (RunBefore) 182 { 183 *pRun++ = RunBefore; 184 } 185 186 return OMX_Sts_NoErr; 187} 188 189/***************************************************************************** 190 * END OF FILE 191 *****************************************************************************/ 192 193