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_4x4.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 4x4 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_4x4   (6.3.3.1.1)
410c1bc742181ded4930842b46e9507372f0b1b963James Dong *
420c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
430c1bc742181ded4930842b46e9507372f0b1b963James Dong * Perform Intra_4x4 prediction for luma samples. If the upper-right block is
440c1bc742181ded4930842b46e9507372f0b1b963James Dong * not available, then duplication work should be handled inside the function.
450c1bc742181ded4930842b46e9507372f0b1b963James Dong * Users need not define them outside.
460c1bc742181ded4930842b46e9507372f0b1b963James Dong *
470c1bc742181ded4930842b46e9507372f0b1b963James Dong * Input Arguments:
480c1bc742181ded4930842b46e9507372f0b1b963James Dong *
490c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcLeft -  Pointer to the buffer of 4 left pixels:
500c1bc742181ded4930842b46e9507372f0b1b963James Dong *                  p[x, y] (x = -1, y = 0..3)
510c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcAbove - Pointer to the buffer of 8 above pixels:
520c1bc742181ded4930842b46e9507372f0b1b963James Dong *                  p[x,y] (x = 0..7, y =-1);
530c1bc742181ded4930842b46e9507372f0b1b963James Dong *               must be aligned on a 4-byte boundary.
540c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
550c1bc742181ded4930842b46e9507372f0b1b963James Dong *   leftStep - Step of left pixel buffer; must be a multiple of 4.
560c1bc742181ded4930842b46e9507372f0b1b963James Dong *   dstStep - Step of the destination buffer; must be a multiple of 4.
570c1bc742181ded4930842b46e9507372f0b1b963James Dong *   predMode - Intra_4x4 prediction mode.
580c1bc742181ded4930842b46e9507372f0b1b963James Dong *   availability - Neighboring 4x4 block availability flag, refer to
590c1bc742181ded4930842b46e9507372f0b1b963James Dong *             "Neighboring Macroblock Availability" .
600c1bc742181ded4930842b46e9507372f0b1b963James Dong *
610c1bc742181ded4930842b46e9507372f0b1b963James Dong * Output Arguments:
620c1bc742181ded4930842b46e9507372f0b1b963James Dong *
630c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pDst - Pointer to the destination buffer; must be aligned on a 4-byte
640c1bc742181ded4930842b46e9507372f0b1b963James Dong *            boundary.
650c1bc742181ded4930842b46e9507372f0b1b963James Dong *
660c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
670c1bc742181ded4930842b46e9507372f0b1b963James Dong *    If the function runs without error, it returns OMX_Sts_NoErr.
680c1bc742181ded4930842b46e9507372f0b1b963James Dong *    If one of the following cases occurs, the function returns
690c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_Sts_BadArgErr:
700c1bc742181ded4930842b46e9507372f0b1b963James Dong *    pDst is NULL.
710c1bc742181ded4930842b46e9507372f0b1b963James Dong *    dstStep < 4, or dstStep is not a multiple of 4.
720c1bc742181ded4930842b46e9507372f0b1b963James Dong *    leftStep is not a multiple of 4.
730c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is not in the valid range of enumeration
740c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMXVCM4P10Intra4x4PredMode.
750c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER
760c1bc742181ded4930842b46e9507372f0b1b963James Dong *              indicating p[x,-1] (x = 0..3) is not available.
770c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT
780c1bc742181ded4930842b46e9507372f0b1b963James Dong *              indicating p[-1,y] (y = 0..3) is not available.
790c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set
800c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER indicating p[x, 1] (x = 0..3) is not available.
810c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set
820c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
830c1bc742181ded4930842b46e9507372f0b1b963James Dong *              p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
840c1bc742181ded4930842b46e9507372f0b1b963James Dong *              available.
850c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_VR, but availability doesn't set
860c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
870c1bc742181ded4930842b46e9507372f0b1b963James Dong *              p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
880c1bc742181ded4930842b46e9507372f0b1b963James Dong *              available.
890c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_HD, but availability doesn't set
900c1bc742181ded4930842b46e9507372f0b1b963James Dong *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
910c1bc742181ded4930842b46e9507372f0b1b963James Dong *              p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not
920c1bc742181ded4930842b46e9507372f0b1b963James Dong *              available.
930c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER
940c1bc742181ded4930842b46e9507372f0b1b963James Dong *              indicating p[x,-1] (x = 0..3) is not available.
950c1bc742181ded4930842b46e9507372f0b1b963James Dong *    predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT
960c1bc742181ded4930842b46e9507372f0b1b963James Dong *              indicating p[-1,y] (y = 0..3) is not available.
970c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
980c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
990c1bc742181ded4930842b46e9507372f0b1b963James Dong *    availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong *    either pSrcAbove or pDst is not aligned on a 4-byte boundary.
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong * Note:
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong *     pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong *     they are not used by intra prediction as implied in predMode.
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong */
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong
1080c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P10_PredictIntra_4x4(
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8* pSrcLeft,
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcAbove,
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcAboveLeft,
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_U8* pDst,
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT leftStep,
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT dstStep,
1150c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMXVCM4P10Intra4x4PredMode predMode,
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_S32 availability
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong )
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong    int x, y;
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8 pTmp[10];
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((leftStep % 4) != 0,  OMX_Sts_BadArgErr);
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((dstStep % 4) != 0,  OMX_Sts_BadArgErr);
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((dstStep < 4),  OMX_Sts_BadArgErr);
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(armNot4ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr);
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_UPPER)      && pSrcAbove     == NULL, OMX_Sts_BadArgErr);
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_LEFT )      && pSrcLeft      == NULL, OMX_Sts_BadArgErr);
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_VERT    && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_HOR     && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DL && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_VR      && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_VR      && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_VR      && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_HD      && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_HD      && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_HD      && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_VL      && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(predMode==OMX_VC_4X4_HU      && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf((unsigned)predMode > OMX_VC_4X4_HU,   OMX_Sts_BadArgErr);
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Note: This code must not read the pSrc arrays unless the corresponding
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong     * block is marked as available. If the block is not avaibable then pSrc
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong     * may not be a valid pointer.
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong     *
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong     * Note: To make the code more readable we refer to the neighbouring pixels
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong     * in variables named as below:
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong     *
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong     *    UL U0 U1 U2 U3 U4 U5 U6 U7
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong     *    L0 xx xx xx xx
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong     *    L1 xx xx xx xx
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong     *    L2 xx xx xx xx
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong     *    L3 xx xx xx xx
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong     */
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong#define UL pSrcAboveLeft[0]
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U0 pSrcAbove[0]
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U1 pSrcAbove[1]
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U2 pSrcAbove[2]
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U3 pSrcAbove[3]
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U4 pSrcAbove[4]
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U5 pSrcAbove[5]
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U6 pSrcAbove[6]
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong#define U7 pSrcAbove[7]
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong#define L0 pSrcLeft[0*leftStep]
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong#define L1 pSrcLeft[1*leftStep]
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong#define L2 pSrcLeft[2*leftStep]
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong#define L3 pSrcLeft[3*leftStep]
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong    switch (predMode)
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_VERT:
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[y*dstStep+0] = U0;
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[y*dstStep+1] = U1;
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[y*dstStep+2] = U2;
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[y*dstStep+3] = U3;
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_HOR:
1880c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (x=0; x<4; x++)
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[0*dstStep+x] = L0;
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[1*dstStep+x] = L1;
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[2*dstStep+x] = L2;
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDst[3*dstStep+x] = L3;
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_DC:
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* This can always be used even if no blocks available */
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong        armVCM4P10_PredictIntraDC4x4(pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability);
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_DIAG_DL:
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (availability & OMX_VC_UPPER_RIGHT)
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[2] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2);
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[3] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2);
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[4] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2);
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[5] = (OMX_U8)((U5 + 2*U6 + U7 + 2)>>2);
2110c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[6] = (OMX_U8)((U6 + 3*U7      + 2)>>2);
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong        else
2140c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2150c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[2] = (OMX_U8)((U2 + 3*U3      + 2)>>2);
2160c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[3] = U3;
2170c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[4] = U3;
2180c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[5] = U3;
2190c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[6] = U3;
2200c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2210c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
2220c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2230c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
2240c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
2250c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[x+y];
2260c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
2270c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2280c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2290c1bc742181ded4930842b46e9507372f0b1b963James Dong
2300c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_DIAG_DR:
2310c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* x-y = -3, -2, -1, 0, 1, 2, 3 */
2320c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
2330c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
2340c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[2] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2);
2350c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[3] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2);
2360c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[4] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2);
2370c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[5] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2);
2380c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[6] = (OMX_U8)((U3 + 2*U2 + U1 + 2)>>2);
2390c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
2400c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2410c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
2420c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
2430c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[3+x-y];
2440c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
2450c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2460c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2470c1bc742181ded4930842b46e9507372f0b1b963James Dong
2480c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_VR:
2490c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* zVR=2x-y = -3, -2, -1, 0, 1, 2, 3, 4, 5, 6
2500c1bc742181ded4930842b46e9507372f0b1b963James Dong         * x-(y>>1) = -1, -1,  0, 0, 1, 1, 2, 2, 3, 3
2510c1bc742181ded4930842b46e9507372f0b1b963James Dong         * y        =  3,  2,  ?, ?, ?, ?, ?, ?, 1, 0
2520c1bc742181ded4930842b46e9507372f0b1b963James Dong         */
2530c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((L2 + 2*L1 + L0 + 2)>>2);
2540c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((L1 + 2*L0 + UL + 2)>>2);
2550c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[2] = (OMX_U8)((L0 + 2*UL + U0 + 2)>>2);
2560c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[3] = (OMX_U8)((UL + U0 + 1)>>1);
2570c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[4] = (OMX_U8)((UL + 2*U0 + U1 + 2)>>2);
2580c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[5] = (OMX_U8)((U0 + U1 + 1)>>1);
2590c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[6] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
2600c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[7] = (OMX_U8)((U1 + U2 + 1)>>1);
2610c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[8] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
2620c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[9] = (OMX_U8)((U2 + U3 + 1)>>1);
2630c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
2640c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2650c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
2660c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
2670c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[3+2*x-y];
2680c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
2690c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2700c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2710c1bc742181ded4930842b46e9507372f0b1b963James Dong
2720c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_HD:
2730c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* zHD=2y-x = -3 -2 -1  0  1  2  3  4  5  6
2740c1bc742181ded4930842b46e9507372f0b1b963James Dong         * y-(x>>1) = -1 -1  0  0  1  1  2  2  3  3
2750c1bc742181ded4930842b46e9507372f0b1b963James Dong         * x        =  3  2                    1  0
2760c1bc742181ded4930842b46e9507372f0b1b963James Dong         */
2770c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2);
2780c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2);
2790c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[2] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2);
2800c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[3] = (OMX_U8)((UL + L0 + 1)>>1);
2810c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[4] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2);
2820c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[5] = (OMX_U8)((L0 + L1 + 1)>>1);
2830c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[6] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
2840c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[7] = (OMX_U8)((L1 + L2 + 1)>>1);
2850c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[8] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
2860c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[9] = (OMX_U8)((L2 + L3 + 1)>>1);
2870c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
2880c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
2890c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
2900c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
2910c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[3+2*y-x];
2920c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
2930c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
2940c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
2950c1bc742181ded4930842b46e9507372f0b1b963James Dong
2960c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_VL:
2970c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* Note: x+(y>>1) = (2*x+y)>>1
2980c1bc742181ded4930842b46e9507372f0b1b963James Dong         * 2x+y = 0 1 2 3 4 5 6 7 8 9
2990c1bc742181ded4930842b46e9507372f0b1b963James Dong         */
3000c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((U0 + U1 + 1)>>1);
3010c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2);
3020c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[2] = (OMX_U8)((U1 + U2 + 1)>>1);
3030c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[3] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2);
3040c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[4] = (OMX_U8)((U2 + U3 + 1)>>1);
3050c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (availability & OMX_VC_UPPER_RIGHT)
3060c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3070c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[5] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2);
3080c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[6] = (OMX_U8)((U3 + U4 + 1)>>1);
3090c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[7] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2);
3100c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[8] = (OMX_U8)((U4 + U5 + 1)>>1);
3110c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[9] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2);
3120c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3130c1bc742181ded4930842b46e9507372f0b1b963James Dong        else
3140c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3150c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[5] = (OMX_U8)((U2 + 3*U3 + 2)>>2);
3160c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[6] = U3;
3170c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[7] = U3;
3180c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[8] = U3;
3190c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTmp[9] = U3;
3200c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3210c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
3220c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3230c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
3240c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3250c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[2*x+y];
3260c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3270c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3280c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
3290c1bc742181ded4930842b46e9507372f0b1b963James Dong
3300c1bc742181ded4930842b46e9507372f0b1b963James Dong    case OMX_VC_4X4_HU:
3310c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* zHU = x+2*y */
3320c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[0] = (OMX_U8)((L0 + L1 + 1)>>1);
3330c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2);
3340c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[2] = (OMX_U8)((L1 + L2 + 1)>>1);
3350c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[3] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2);
3360c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[4] = (OMX_U8)((L2 + L3 + 1)>>1);
3370c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[5] = (OMX_U8)((L2 + 3*L3 + 2)>>2);
3380c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[6] = L3;
3390c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[7] = L3;
3400c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[8] = L3;
3410c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTmp[9] = L3;
3420c1bc742181ded4930842b46e9507372f0b1b963James Dong        for (y=0; y<4; y++)
3430c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3440c1bc742181ded4930842b46e9507372f0b1b963James Dong            for (x=0; x<4; x++)
3450c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3460c1bc742181ded4930842b46e9507372f0b1b963James Dong                pDst[y*dstStep+x] = pTmp[x+2*y];
3470c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3480c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3490c1bc742181ded4930842b46e9507372f0b1b963James Dong        break;
3500c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
3510c1bc742181ded4930842b46e9507372f0b1b963James Dong
3520c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
3530c1bc742181ded4930842b46e9507372f0b1b963James Dong}
354