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