178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar/*
278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Copyright (C) 2007-2008 ARM Limited
378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar *
478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * you may not use this file except in compliance with the License.
678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * You may obtain a copy of the License at
778e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar *
878e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
978e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar *
1078e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Unless required by applicable law or agreed to in writing, software
1178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * See the License for the specific language governing permissions and
1478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * limitations under the License.
1578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar *
1678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar */
170c1bc742181ded4930842b46e9507372f0b1b963James Dong/* ----------------------------------------------------------------
180c1bc742181ded4930842b46e9507372f0b1b963James Dong *
190c1bc742181ded4930842b46e9507372f0b1b963James Dong *
200c1bc742181ded4930842b46e9507372f0b1b963James Dong * File Name:  omxVCM4P10_PredictIntra_16x16.c
210c1bc742181ded4930842b46e9507372f0b1b963James Dong * OpenMAX DL: v1.0.2
220c1bc742181ded4930842b46e9507372f0b1b963James Dong * Revision:   9641
230c1bc742181ded4930842b46e9507372f0b1b963James Dong * Date:       Thursday, February 7, 2008
240c1bc742181ded4930842b46e9507372f0b1b963James Dong *
250c1bc742181ded4930842b46e9507372f0b1b963James Dong *
260c1bc742181ded4930842b46e9507372f0b1b963James Dong *
270c1bc742181ded4930842b46e9507372f0b1b963James Dong *
280c1bc742181ded4930842b46e9507372f0b1b963James Dong * H.264 16x16 intra prediction module
290c1bc742181ded4930842b46e9507372f0b1b963James Dong *
300c1bc742181ded4930842b46e9507372f0b1b963James Dong */
310c1bc742181ded4930842b46e9507372f0b1b963James Dong
320c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxtypes.h"
330c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armOMX.h"
340c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxVC.h"
350c1bc742181ded4930842b46e9507372f0b1b963James Dong
360c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM.h"
370c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVC.h"
380c1bc742181ded4930842b46e9507372f0b1b963James Dong
390c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
400c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function:  omxVCM4P10_PredictIntra_16x16   (6.3.3.1.2)
410c1bc742181ded4930842b46e9507372f0b1b963James Dong *
420c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
430c1bc742181ded4930842b46e9507372f0b1b963James Dong * Perform Intra_16x16 prediction for luma samples. If the upper-right block
440c1bc742181ded4930842b46e9507372f0b1b963James Dong * is not available, then duplication work should be handled inside the
450c1bc742181ded4930842b46e9507372f0b1b963James Dong * function. Users need not define them outside.
460c1bc742181ded4930842b46e9507372f0b1b963James Dong *
470c1bc742181ded4930842b46e9507372f0b1b963James Dong * Input Arguments:
480c1bc742181ded4930842b46e9507372f0b1b963James Dong *
490c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
500c1bc742181ded4930842b46e9507372f0b1b963James Dong *            0..15)
510c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
520c1bc742181ded4930842b46e9507372f0b1b963James Dong *            y= -1); must be aligned on a 16-byte boundary.
530c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
540c1bc742181ded4930842b46e9507372f0b1b963James Dong *   leftStep - Step of left pixel buffer; must be a multiple of 16.
550c1bc742181ded4930842b46e9507372f0b1b963James Dong *   dstStep - Step of the destination buffer; must be a multiple of 16.
560c1bc742181ded4930842b46e9507372f0b1b963James Dong *   predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
570c1bc742181ded4930842b46e9507372f0b1b963James Dong *   availability - Neighboring 16x16 MB availability flag. Refer to
580c1bc742181ded4930842b46e9507372f0b1b963James Dong *                  section 3.4.4.
590c1bc742181ded4930842b46e9507372f0b1b963James Dong *
600c1bc742181ded4930842b46e9507372f0b1b963James Dong * Output Arguments:
610c1bc742181ded4930842b46e9507372f0b1b963James Dong *
620c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pDst -Pointer to the destination buffer; must be aligned on a 16-byte
630c1bc742181ded4930842b46e9507372f0b1b963James Dong *            boundary.
640c1bc742181ded4930842b46e9507372f0b1b963James Dong *
650c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
660c1bc742181ded4930842b46e9507372f0b1b963James Dong *    If the function runs without error, it returns OMX_Sts_NoErr.
670c1bc742181ded4930842b46e9507372f0b1b963James Dong *    If one of the following cases occurs, the function returns
680c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_Sts_BadArgErr:
690c1bc742181ded4930842b46e9507372f0b1b963James Dong *    pDst is NULL.
700c1bc742181ded4930842b46e9507372f0b1b963James Dong *    dstStep < 16. or dstStep is not a multiple of 16.
710c1bc742181ded4930842b46e9507372f0b1b963James Dong *    leftStep is not a multiple of 16.
720c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is not in the valid range of enumeration
730c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMXVCM4P10Intra16x16PredMode
740c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_16X16_VERT, but availability doesn't set
750c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
760c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
770c1bc742181ded4930842b46e9507372f0b1b963James Dong *              indicating p[-1,y] (y = 0..15) is not available.
780c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_16X16_PLANE, but availability doesn't set
790c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
800c1bc742181ded4930842b46e9507372f0b1b963James Dong *              p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
810c1bc742181ded4930842b46e9507372f0b1b963James Dong *              available.
820c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
830c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
840c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
850c1bc742181ded4930842b46e9507372f0b1b963James Dong *    either pSrcAbove or pDst is not aligned on a 16-byte boundary.
860c1bc742181ded4930842b46e9507372f0b1b963James Dong *
870c1bc742181ded4930842b46e9507372f0b1b963James Dong * Note:
880c1bc742181ded4930842b46e9507372f0b1b963James Dong *     pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
890c1bc742181ded4930842b46e9507372f0b1b963James Dong *     they are not used by intra prediction implied in predMode.
900c1bc742181ded4930842b46e9507372f0b1b963James Dong * Note:
910c1bc742181ded4930842b46e9507372f0b1b963James Dong *     OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
920c1bc742181ded4930842b46e9507372f0b1b963James Dong *
930c1bc742181ded4930842b46e9507372f0b1b963James Dong */
940c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P10_PredictIntra_16x16(
950c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8* pSrcLeft,
960c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8 *pSrcAbove,
970c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8 *pSrcAboveLeft,
980c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8* pDst,
990c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT leftStep,
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT dstStep,
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P10Intra16x16PredMode predMode,
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S32 availability)
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong    int x,y,Sum,Count;
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong    int H,V,a,b,c;
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(dstStep < 16,  OMX_Sts_BadArgErr);
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((dstStep % 16) != 0,  OMX_Sts_BadArgErr);
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((leftStep % 16) != 0,  OMX_Sts_BadArgErr);
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr);
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_UPPER)      && pSrcAbove     == NULL, OMX_Sts_BadArgErr);
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_LEFT )      && pSrcLeft      == NULL, OMX_Sts_BadArgErr);
1150c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_16X16_VERT  && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_16X16_HOR   && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE,  OMX_Sts_BadArgErr);
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong    switch (predMode)
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_16X16_VERT:
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<16; y++)
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<16; x++)
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pSrcAbove[x];
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_16X16_HOR:
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<16; y++)
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<16; x++)
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pSrcLeft[y*leftStep];
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_16X16_DC:
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* This can always be used even if no blocks available */
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong        Sum = 0;
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong        Count = 0;
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (availability & OMX_VC_LEFT)
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (y=0; y<16; y++)
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong                Sum += pSrcLeft[y*leftStep];
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong            Count++;
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (availability & OMX_VC_UPPER)
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<16; x++)
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong                Sum += pSrcAbove[x];
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong            Count++;
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (Count==0)
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong            Sum = 128;
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong        else if (Count==1)
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong            Sum = (Sum + 8) >> 4;
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong        else /* Count = 2 */
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong            Sum = (Sum + 16) >> 5;
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<16; y++)
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<16; x++)
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = (OMX_U8)Sum;
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_16X16_PLANE:
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong        H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]);
1880c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (x=6; x>=0; x--)
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong            H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]);
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong        V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]);
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=6; y>=0; y--)
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong            V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]);
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong        a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]);
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong        b = (5*H+32)>>6;
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong        c = (5*V+32)>>6;
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<16; y++)
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<16; x++)
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong                Sum = (a + b*(x-7) + c*(y-7) + 16)>>5;
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum);
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong
2110c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong
214