1 /* ---------------------------------------------------------------- 2 * 3 * 4 * File Name: omxVCM4P10_PredictIntra_16x16.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 16x16 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 * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2) 26 * 27 * Description: 28 * Perform Intra_16x16 prediction for luma samples. If the upper-right block 29 * is not available, then duplication work should be handled inside the 30 * function. Users need not define them outside. 31 * 32 * Input Arguments: 33 * 34 * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y = 35 * 0..15) 36 * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15, 37 * y= -1); must be aligned on a 16-byte boundary. 38 * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) 39 * leftStep - Step of left pixel buffer; must be a multiple of 16. 40 * dstStep - Step of the destination buffer; must be a multiple of 16. 41 * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1. 42 * availability - Neighboring 16x16 MB availability flag. Refer to 43 * section 3.4.4. 44 * 45 * Output Arguments: 46 * 47 * pDst -Pointer to the destination buffer; must be aligned on a 16-byte 48 * boundary. 49 * 50 * Return Value: 51 * If the function runs without error, it returns OMX_Sts_NoErr. 52 * If one of the following cases occurs, the function returns 53 * OMX_Sts_BadArgErr: 54 * pDst is NULL. 55 * dstStep < 16. or dstStep is not a multiple of 16. 56 * leftStep is not a multiple of 16. 57 * predMode is not in the valid range of enumeration 58 * OMXVCM4P10Intra16x16PredMode 59 * predMode is OMX_VC_16X16_VERT, but availability doesn't set 60 * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available. 61 * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT 62 * indicating p[-1,y] (y = 0..15) is not available. 63 * predMode is OMX_VC_16X16_PLANE, but availability doesn't set 64 * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating 65 * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not 66 * available. 67 * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. 68 * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. 69 * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. 70 * either pSrcAbove or pDst is not aligned on a 16-byte boundary. 71 * 72 * Note: 73 * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if 74 * they are not used by intra prediction implied in predMode. 75 * Note: 76 * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction. 77 * 78 */ 79 OMXResult omxVCM4P10_PredictIntra_16x16( 80 const OMX_U8* pSrcLeft, 81 const OMX_U8 *pSrcAbove, 82 const OMX_U8 *pSrcAboveLeft, 83 OMX_U8* pDst, 84 OMX_INT leftStep, 85 OMX_INT dstStep, 86 OMXVCM4P10Intra16x16PredMode predMode, 87 OMX_S32 availability) 88 { 89 int x,y,Sum,Count; 90 int H,V,a,b,c; 91 92 armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); 93 armRetArgErrIf(dstStep < 16, OMX_Sts_BadArgErr); 94 armRetArgErrIf((dstStep % 16) != 0, OMX_Sts_BadArgErr); 95 armRetArgErrIf((leftStep % 16) != 0, OMX_Sts_BadArgErr); 96 armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); 97 armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr); 98 armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); 99 armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); 100 armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); 101 armRetArgErrIf(predMode==OMX_VC_16X16_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); 102 armRetArgErrIf(predMode==OMX_VC_16X16_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); 103 armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); 104 armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); 105 armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); 106 armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE, OMX_Sts_BadArgErr); 107 108 switch (predMode) 109 { 110 case OMX_VC_16X16_VERT: 111 for (y=0; y<16; y++) 112 { 113 for (x=0; x<16; x++) 114 { 115 pDst[y*dstStep+x] = pSrcAbove[x]; 116 } 117 } 118 break; 119 120 case OMX_VC_16X16_HOR: 121 for (y=0; y<16; y++) 122 { 123 for (x=0; x<16; x++) 124 { 125 pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; 126 } 127 } 128 break; 129 130 case OMX_VC_16X16_DC: 131 /* This can always be used even if no blocks available */ 132 Sum = 0; 133 Count = 0; 134 if (availability & OMX_VC_LEFT) 135 { 136 for (y=0; y<16; y++) 137 { 138 Sum += pSrcLeft[y*leftStep]; 139 } 140 Count++; 141 } 142 if (availability & OMX_VC_UPPER) 143 { 144 for (x=0; x<16; x++) 145 { 146 Sum += pSrcAbove[x]; 147 } 148 Count++; 149 } 150 if (Count==0) 151 { 152 Sum = 128; 153 } 154 else if (Count==1) 155 { 156 Sum = (Sum + 8) >> 4; 157 } 158 else /* Count = 2 */ 159 { 160 Sum = (Sum + 16) >> 5; 161 } 162 for (y=0; y<16; y++) 163 { 164 for (x=0; x<16; x++) 165 { 166 pDst[y*dstStep+x] = (OMX_U8)Sum; 167 } 168 } 169 break; 170 171 case OMX_VC_16X16_PLANE: 172 H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]); 173 for (x=6; x>=0; x--) 174 { 175 H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]); 176 } 177 V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]); 178 for (y=6; y>=0; y--) 179 { 180 V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]); 181 } 182 a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]); 183 b = (5*H+32)>>6; 184 c = (5*V+32)>>6; 185 for (y=0; y<16; y++) 186 { 187 for (x=0; x<16; x++) 188 { 189 Sum = (a + b*(x-7) + c*(y-7) + 16)>>5; 190 pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); 191 } 192 } 193 break; 194 } 195 196 return OMX_Sts_NoErr; 197 } 198 199