| /* |
| * Copyright (C) 2007-2008 ARM Limited |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| /* ---------------------------------------------------------------- |
| * |
| * |
| * File Name: omxVCM4P10_PredictIntra_16x16.c |
| * OpenMAX DL: v1.0.2 |
| * Revision: 9641 |
| * Date: Thursday, February 7, 2008 |
| * |
| * |
| * |
| * |
| * H.264 16x16 intra prediction module |
| * |
| */ |
| |
| #include "omxtypes.h" |
| #include "armOMX.h" |
| #include "omxVC.h" |
| |
| #include "armCOMM.h" |
| #include "armVC.h" |
| |
| /** |
| * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2) |
| * |
| * Description: |
| * Perform Intra_16x16 prediction for luma samples. If the upper-right block |
| * is not available, then duplication work should be handled inside the |
| * function. Users need not define them outside. |
| * |
| * Input Arguments: |
| * |
| * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y = |
| * 0..15) |
| * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15, |
| * y= -1); must be aligned on a 16-byte boundary. |
| * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) |
| * leftStep - Step of left pixel buffer; must be a multiple of 16. |
| * dstStep - Step of the destination buffer; must be a multiple of 16. |
| * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1. |
| * availability - Neighboring 16x16 MB availability flag. Refer to |
| * section 3.4.4. |
| * |
| * Output Arguments: |
| * |
| * pDst -Pointer to the destination buffer; must be aligned on a 16-byte |
| * boundary. |
| * |
| * Return Value: |
| * If the function runs without error, it returns OMX_Sts_NoErr. |
| * If one of the following cases occurs, the function returns |
| * OMX_Sts_BadArgErr: |
| * pDst is NULL. |
| * dstStep < 16. or dstStep is not a multiple of 16. |
| * leftStep is not a multiple of 16. |
| * predMode is not in the valid range of enumeration |
| * OMXVCM4P10Intra16x16PredMode |
| * predMode is OMX_VC_16X16_VERT, but availability doesn't set |
| * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available. |
| * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT |
| * indicating p[-1,y] (y = 0..15) is not available. |
| * predMode is OMX_VC_16X16_PLANE, but availability doesn't set |
| * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating |
| * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not |
| * available. |
| * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. |
| * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. |
| * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. |
| * either pSrcAbove or pDst is not aligned on a 16-byte boundary. |
| * |
| * Note: |
| * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if |
| * they are not used by intra prediction implied in predMode. |
| * Note: |
| * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction. |
| * |
| */ |
| OMXResult omxVCM4P10_PredictIntra_16x16( |
| const OMX_U8* pSrcLeft, |
| const OMX_U8 *pSrcAbove, |
| const OMX_U8 *pSrcAboveLeft, |
| OMX_U8* pDst, |
| OMX_INT leftStep, |
| OMX_INT dstStep, |
| OMXVCM4P10Intra16x16PredMode predMode, |
| OMX_S32 availability) |
| { |
| int x,y,Sum,Count; |
| int H,V,a,b,c; |
| |
| armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(dstStep < 16, OMX_Sts_BadArgErr); |
| armRetArgErrIf((dstStep % 16) != 0, OMX_Sts_BadArgErr); |
| armRetArgErrIf((leftStep % 16) != 0, OMX_Sts_BadArgErr); |
| armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); |
| armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr); |
| armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(predMode==OMX_VC_16X16_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); |
| armRetArgErrIf(predMode==OMX_VC_16X16_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); |
| armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); |
| armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); |
| armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); |
| armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE, OMX_Sts_BadArgErr); |
| |
| switch (predMode) |
| { |
| case OMX_VC_16X16_VERT: |
| for (y=0; y<16; y++) |
| { |
| for (x=0; x<16; x++) |
| { |
| pDst[y*dstStep+x] = pSrcAbove[x]; |
| } |
| } |
| break; |
| |
| case OMX_VC_16X16_HOR: |
| for (y=0; y<16; y++) |
| { |
| for (x=0; x<16; x++) |
| { |
| pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; |
| } |
| } |
| break; |
| |
| case OMX_VC_16X16_DC: |
| /* This can always be used even if no blocks available */ |
| Sum = 0; |
| Count = 0; |
| if (availability & OMX_VC_LEFT) |
| { |
| for (y=0; y<16; y++) |
| { |
| Sum += pSrcLeft[y*leftStep]; |
| } |
| Count++; |
| } |
| if (availability & OMX_VC_UPPER) |
| { |
| for (x=0; x<16; x++) |
| { |
| Sum += pSrcAbove[x]; |
| } |
| Count++; |
| } |
| if (Count==0) |
| { |
| Sum = 128; |
| } |
| else if (Count==1) |
| { |
| Sum = (Sum + 8) >> 4; |
| } |
| else /* Count = 2 */ |
| { |
| Sum = (Sum + 16) >> 5; |
| } |
| for (y=0; y<16; y++) |
| { |
| for (x=0; x<16; x++) |
| { |
| pDst[y*dstStep+x] = (OMX_U8)Sum; |
| } |
| } |
| break; |
| |
| case OMX_VC_16X16_PLANE: |
| H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]); |
| for (x=6; x>=0; x--) |
| { |
| H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]); |
| } |
| V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]); |
| for (y=6; y>=0; y--) |
| { |
| V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]); |
| } |
| a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]); |
| b = (5*H+32)>>6; |
| c = (5*V+32)>>6; |
| for (y=0; y<16; y++) |
| { |
| for (x=0; x<16; x++) |
| { |
| Sum = (a + b*(x-7) + c*(y-7) + 16)>>5; |
| pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); |
| } |
| } |
| break; |
| } |
| |
| return OMX_Sts_NoErr; |
| } |
| |