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