1/* ---------------------------------------------------------------- 2 * 3 * 4 * File Name: omxVCM4P10_PredictIntraChroma_8x8.c 5 * OpenMAX DL: v1.0.2 6 * Revision: 9641 7 * Date: Thursday, February 7, 2008 8 * 9 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 10 * 11 * 12 * 13 * H.264 Chroma 8x8 intra prediction module 14 * 15 */ 16 17#include "omxtypes.h" 18#include "armOMX.h" 19#include "omxVC.h" 20 21#include "armCOMM.h" 22#include "armVC.h" 23 24/* 25 * Description: 26 * Perform DC style intra prediction, upper block has priority 27 * 28 * Parameters: 29 * [in] pSrcLeft Pointer to the buffer of 16 left coefficients: 30 * p[x, y] (x = -1, y = 0..3) 31 * [in] pSrcAbove Pointer to the buffer of 16 above coefficients: 32 * p[x,y] (x = 0..3, y = -1) 33 * [in] leftStep Step of left coefficient buffer 34 * [in] dstStep Step of the destination buffer 35 * [in] availability Neighboring 16x16 MB availability flag 36 * [out] pDst Pointer to the destination buffer 37 * 38 * Return Value: 39 * None 40 */ 41 42static void armVCM4P10_PredictIntraDCUp4x4( 43 const OMX_U8* pSrcLeft, 44 const OMX_U8 *pSrcAbove, 45 OMX_U8* pDst, 46 OMX_INT leftStep, 47 OMX_INT dstStep, 48 OMX_S32 availability 49) 50{ 51 int x, y, Sum=0, Count = 0; 52 53 if (availability & OMX_VC_UPPER) 54 { 55 for (x=0; x<4; x++) 56 { 57 Sum += pSrcAbove[x]; 58 } 59 Count++; 60 } 61 else if (availability & OMX_VC_LEFT) 62 { 63 for (y=0; y<4; y++) 64 { 65 Sum += pSrcLeft[y*leftStep]; 66 } 67 Count++; 68 } 69 if (Count==0) 70 { 71 Sum = 128; 72 } 73 else 74 { 75 Sum = (Sum + 2) >> 2; 76 } 77 for (y=0; y<4; y++) 78 { 79 for (x=0; x<4; x++) 80 { 81 pDst[y*dstStep+x] = (OMX_U8)Sum; 82 } 83 } 84} 85 86/* 87 * Description: 88 * Perform DC style intra prediction, left block has priority 89 * 90 * Parameters: 91 * [in] pSrcLeft Pointer to the buffer of 16 left coefficients: 92 * p[x, y] (x = -1, y = 0..3) 93 * [in] pSrcAbove Pointer to the buffer of 16 above coefficients: 94 * p[x,y] (x = 0..3, y = -1) 95 * [in] leftStep Step of left coefficient buffer 96 * [in] dstStep Step of the destination buffer 97 * [in] availability Neighboring 16x16 MB availability flag 98 * [out] pDst Pointer to the destination buffer 99 * 100 * Return Value: 101 * None 102 */ 103 104static void armVCM4P10_PredictIntraDCLeft4x4( 105 const OMX_U8* pSrcLeft, 106 const OMX_U8 *pSrcAbove, 107 OMX_U8* pDst, 108 OMX_INT leftStep, 109 OMX_INT dstStep, 110 OMX_S32 availability 111) 112{ 113 int x, y, Sum=0, Count = 0; 114 115 if (availability & OMX_VC_LEFT) 116 { 117 for (y=0; y<4; y++) 118 { 119 Sum += pSrcLeft[y*leftStep]; 120 } 121 Count++; 122 } 123 else if (availability & OMX_VC_UPPER) 124 { 125 for (x=0; x<4; x++) 126 { 127 Sum += pSrcAbove[x]; 128 } 129 Count++; 130 } 131 if (Count==0) 132 { 133 Sum = 128; 134 } 135 else 136 { 137 Sum = (Sum + 2) >> 2; 138 } 139 for (y=0; y<4; y++) 140 { 141 for (x=0; x<4; x++) 142 { 143 pDst[y*dstStep+x] = (OMX_U8)Sum; 144 } 145 } 146} 147 148/** 149 * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3) 150 * 151 * Description: 152 * Performs intra prediction for chroma samples. 153 * 154 * Input Arguments: 155 * 156 * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y= 157 * 0..7). 158 * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y 159 * = -1); must be aligned on an 8-byte boundary. 160 * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) 161 * leftStep - Step of left pixel buffer; must be a multiple of 8. 162 * dstStep - Step of the destination buffer; must be a multiple of 8. 163 * predMode - Intra chroma prediction mode, please refer to section 3.4.3. 164 * availability - Neighboring chroma block availability flag, please refer 165 * to "Neighboring Macroblock Availability". 166 * 167 * Output Arguments: 168 * 169 * pDst - Pointer to the destination buffer; must be aligned on an 8-byte 170 * boundary. 171 * 172 * Return Value: 173 * If the function runs without error, it returns OMX_Sts_NoErr. 174 * If any of the following cases occurs, the function returns 175 * OMX_Sts_BadArgErr: 176 * pDst is NULL. 177 * dstStep < 8 or dstStep is not a multiple of 8. 178 * leftStep is not a multiple of 8. 179 * predMode is not in the valid range of enumeration 180 * OMXVCM4P10IntraChromaPredMode. 181 * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set 182 * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available. 183 * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT 184 * indicating p[-1,y] (y = 0..7) is not available. 185 * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set 186 * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating 187 * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not 188 * available. 189 * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. 190 * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. 191 * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. 192 * either pSrcAbove or pDst is not aligned on a 8-byte boundary. Note: 193 * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if 194 * they are not used by intra prediction implied in predMode. 195 * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma 196 * prediction. 197 * 198 */ 199OMXResult omxVCM4P10_PredictIntraChroma_8x8( 200 const OMX_U8* pSrcLeft, 201 const OMX_U8 *pSrcAbove, 202 const OMX_U8 *pSrcAboveLeft, 203 OMX_U8* pDst, 204 OMX_INT leftStep, 205 OMX_INT dstStep, 206 OMXVCM4P10IntraChromaPredMode predMode, 207 OMX_S32 availability 208 ) 209{ 210 int x, y, Sum; 211 int H, V, a, b, c; 212 213 armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); 214 armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr); 215 armRetArgErrIf((dstStep % 8) != 0, OMX_Sts_BadArgErr); 216 armRetArgErrIf((leftStep % 8) != 0, OMX_Sts_BadArgErr); 217 armRetArgErrIf(armNot8ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); 218 armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr); 219 armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); 220 armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); 221 armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); 222 armRetArgErrIf(predMode==OMX_VC_CHROMA_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); 223 armRetArgErrIf(predMode==OMX_VC_CHROMA_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); 224 armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); 225 armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); 226 armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); 227 armRetArgErrIf((unsigned)predMode > OMX_VC_CHROMA_PLANE, OMX_Sts_BadArgErr); 228 229 switch (predMode) 230 { 231 case OMX_VC_CHROMA_DC: 232 armVCM4P10_PredictIntraDC4x4( pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability); 233 armVCM4P10_PredictIntraDCUp4x4( pSrcLeft, pSrcAbove+4, pDst+4, leftStep, dstStep, availability); 234 armVCM4P10_PredictIntraDCLeft4x4( pSrcLeft+4*leftStep, pSrcAbove, pDst+4*dstStep, leftStep, dstStep, availability); 235 armVCM4P10_PredictIntraDC4x4( pSrcLeft+4*leftStep, pSrcAbove+4, pDst+4+4*dstStep, leftStep, dstStep, availability); 236 break; 237 238 case OMX_VC_CHROMA_HOR: 239 for (y=0; y<8; y++) 240 { 241 for (x=0; x<8; x++) 242 { 243 pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; 244 } 245 } 246 break; 247 248 case OMX_VC_CHROMA_VERT: 249 for (y=0; y<8; y++) 250 { 251 for (x=0; x<8; x++) 252 { 253 pDst[y*dstStep+x] = pSrcAbove[x]; 254 } 255 } 256 break; 257 258 case OMX_VC_CHROMA_PLANE: 259 H = 4*(pSrcAbove[7] - pSrcAboveLeft[0]); 260 for (x=2; x>=0; x--) 261 { 262 H += (x+1)*(pSrcAbove[4+x] - pSrcAbove[2-x]); 263 } 264 V = 4*(pSrcLeft[7*leftStep] - pSrcAboveLeft[0]); 265 for (y=2; y>=0; y--) 266 { 267 V += (y+1)*(pSrcLeft[(4+y)*leftStep] - pSrcLeft[(2-y)*leftStep]); 268 } 269 a = 16*(pSrcAbove[7] + pSrcLeft[7*leftStep]); 270 b = (17*H+16)>>5; 271 c = (17*V+16)>>5; 272 for (y=0; y<8; y++) 273 { 274 for (x=0; x<8; x++) 275 { 276 Sum = (a + b*(x-3) + c*(y-3) + 16)>>5; 277 pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); 278 } 279 } 280 break; 281 } 282 283 return OMX_Sts_NoErr; 284} 285