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