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