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 * File Name: omxVCM4P2_EncodeMV.c 200c1bc742181ded4930842b46e9507372f0b1b963James Dong * OpenMAX DL: v1.0.2 210c1bc742181ded4930842b46e9507372f0b1b963James Dong * Revision: 9641 220c1bc742181ded4930842b46e9507372f0b1b963James Dong * Date: Thursday, February 7, 2008 230c1bc742181ded4930842b46e9507372f0b1b963James Dong * 240c1bc742181ded4930842b46e9507372f0b1b963James Dong * 250c1bc742181ded4930842b46e9507372f0b1b963James Dong * 260c1bc742181ded4930842b46e9507372f0b1b963James Dong * 270c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Contains module for predicting MV of MB 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 "armCOMM_Bitstream.h" 380c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVCM4P2_Huff_Tables_VLC.h" 390c1bc742181ded4930842b46e9507372f0b1b963James Dong 400c1bc742181ded4930842b46e9507372f0b1b963James Dong 410c1bc742181ded4930842b46e9507372f0b1b963James Dong 420c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 430c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: omxVCM4P2_EncodeMV (6.2.4.5.4) 440c1bc742181ded4930842b46e9507372f0b1b963James Dong * 450c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 460c1bc742181ded4930842b46e9507372f0b1b963James Dong * Predicts a motion vector for the current macroblock, encodes the 470c1bc742181ded4930842b46e9507372f0b1b963James Dong * difference, and writes the output to the stream buffer. The input MVs 480c1bc742181ded4930842b46e9507372f0b1b963James Dong * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie 490c1bc742181ded4930842b46e9507372f0b1b963James Dong * within the ranges associated with the input parameter fcodeForward, as 500c1bc742181ded4930842b46e9507372f0b1b963James Dong * described in [ISO14496-2], subclause 7.6.3. This function provides a 510c1bc742181ded4930842b46e9507372f0b1b963James Dong * superset of the functionality associated with the function 520c1bc742181ded4930842b46e9507372f0b1b963James Dong * omxVCM4P2_FindMVpred. 530c1bc742181ded4930842b46e9507372f0b1b963James Dong * 540c1bc742181ded4930842b46e9507372f0b1b963James Dong * Input Arguments: 550c1bc742181ded4930842b46e9507372f0b1b963James Dong * 560c1bc742181ded4930842b46e9507372f0b1b963James Dong * ppBitStream - double pointer to the current byte in the bitstream buffer 570c1bc742181ded4930842b46e9507372f0b1b963James Dong * pBitOffset - index of the first free (next available) bit in the stream 580c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer referenced by *ppBitStream, valid in the range 0 to 7. 590c1bc742181ded4930842b46e9507372f0b1b963James Dong * pMVCurMB - pointer to the current macroblock motion vector; a value of 600c1bc742181ded4930842b46e9507372f0b1b963James Dong * NULL indicates unavailability. 610c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a 620c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULLindicates unavailability. 630c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a 640c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULL indicates unavailability. 650c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a 660c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULL indicates unavailability. 670c1bc742181ded4930842b46e9507372f0b1b963James Dong * fcodeForward - an integer with values from 1 to 7; used in encoding 680c1bc742181ded4930842b46e9507372f0b1b963James Dong * motion vectors related to search range, as described in 690c1bc742181ded4930842b46e9507372f0b1b963James Dong * [ISO14496-2], subclause 7.6.3. 700c1bc742181ded4930842b46e9507372f0b1b963James Dong * MBType - macro block type, valid in the range 0 to 5 710c1bc742181ded4930842b46e9507372f0b1b963James Dong * 720c1bc742181ded4930842b46e9507372f0b1b963James Dong * Output Arguments: 730c1bc742181ded4930842b46e9507372f0b1b963James Dong * 740c1bc742181ded4930842b46e9507372f0b1b963James Dong * ppBitStream - updated pointer to the current byte in the bit stream 750c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer 760c1bc742181ded4930842b46e9507372f0b1b963James Dong * pBitOffset - updated index of the next available bit position in stream 770c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer referenced by *ppBitStream 780c1bc742181ded4930842b46e9507372f0b1b963James Dong * 790c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value: 800c1bc742181ded4930842b46e9507372f0b1b963James Dong * 810c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr - no error 820c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr - bad arguments 830c1bc742181ded4930842b46e9507372f0b1b963James Dong * - At least one of the following pointers is NULL: ppBitStream, 840c1bc742181ded4930842b46e9507372f0b1b963James Dong * *ppBitStream, pBitOffset, pMVCurMB 850c1bc742181ded4930842b46e9507372f0b1b963James Dong * - *pBitOffset < 0, or *pBitOffset >7. 860c1bc742181ded4930842b46e9507372f0b1b963James Dong * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0. 870c1bc742181ded4930842b46e9507372f0b1b963James Dong * 880c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 890c1bc742181ded4930842b46e9507372f0b1b963James Dong 900c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P2_EncodeMV( 910c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 **ppBitStream, 920c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT *pBitOffset, 930c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pMVCurMB, 940c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVLeftMB, 950c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVUpperMB, 960c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVUpperRightMB, 970c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT fcodeForward, 980c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCM4P2MacroblockType MBType 990c1bc742181ded4930842b46e9507372f0b1b963James Dong) 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector dstMVPred, diffMV; 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector dstMVPredME[12]; 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Initialized to remove compilation warning */ 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT iBlk, i, count = 1; 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData; 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 scaleFactor, index; 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Argument error checks */ 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr); 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr); 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \ 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_Sts_BadArgErr); 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((MBType == OMX_VC_INTRA) || 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong (MBType == OMX_VC_INTRA_Q) 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong ) 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong /* No candidate vectors hence make them zero */ 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = 0; i < 12; i++) 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME[i].dx = 0; 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME[i].dy = 0; 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q)) 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong count = 4; 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q)) 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong count = 1; 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the scale factor */ 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong scaleFactor = 1 << (fcodeForward -1); 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong for (iBlk = 0; iBlk < count; iBlk++) 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Find the predicted vector */ 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong omxVCM4P2_FindMVpred ( 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong pMVCurMB, 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVLeftMB, 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVUpperMB, 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVUpperRightMB, 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong &dstMVPred, 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME, 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong iBlk ); 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the differential motion vector (diffMV) */ 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx; 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy; 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the mv_data and mv_residual for Horizantal MV */ 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dx == 0) 1620c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1630c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorResidual = 0; 1640c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = 0; 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong else 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1680c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor; 1690c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1)) 1700c1bc742181ded4930842b46e9507372f0b1b963James Dong / scaleFactor; 1710c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dx < 0) 1720c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1730c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = -mvHorData; 1740c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1750c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1760c1bc742181ded4930842b46e9507372f0b1b963James Dong 1770c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the mv_data and mv_residual for Vertical MV */ 1780c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dy == 0) 1790c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1800c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerResidual = 0; 1810c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = 0; 1820c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1830c1bc742181ded4930842b46e9507372f0b1b963James Dong else 1840c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1850c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor; 1860c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1)) 1870c1bc742181ded4930842b46e9507372f0b1b963James Dong / scaleFactor; 1880c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dy < 0) 1890c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1900c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = -mvVerData; 1910c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1920c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1930c1bc742181ded4930842b46e9507372f0b1b963James Dong 1940c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Huffman encoding */ 1950c1bc742181ded4930842b46e9507372f0b1b963James Dong 1960c1bc742181ded4930842b46e9507372f0b1b963James Dong /* The index is actually calculate as 1970c1bc742181ded4930842b46e9507372f0b1b963James Dong index = ((float) (mvHorData/2) + 16) * 2, 1980c1bc742181ded4930842b46e9507372f0b1b963James Dong meaning the MV data is halfed and then normalized 1990c1bc742181ded4930842b46e9507372f0b1b963James Dong to begin with zero and then doubled to take care of indexing 2000c1bc742181ded4930842b46e9507372f0b1b963James Dong the fractional part included */ 2010c1bc742181ded4930842b46e9507372f0b1b963James Dong index = mvHorData + 32; 2020c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 2030c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((fcodeForward > 1) && (diffMV.dx != 0)) 2040c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2050c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1)); 2060c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2070c1bc742181ded4930842b46e9507372f0b1b963James Dong 2080c1bc742181ded4930842b46e9507372f0b1b963James Dong /* The index is actually calculate as 2090c1bc742181ded4930842b46e9507372f0b1b963James Dong index = ((float) (mvVerData/2) + 16) * 2, 2100c1bc742181ded4930842b46e9507372f0b1b963James Dong meaning the MV data is halfed and then normalized 2110c1bc742181ded4930842b46e9507372f0b1b963James Dong to begin with zero and then doubled to take care of indexing 2120c1bc742181ded4930842b46e9507372f0b1b963James Dong the fractional part included */ 2130c1bc742181ded4930842b46e9507372f0b1b963James Dong index = mvVerData + 32; 2140c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 2150c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((fcodeForward > 1) && (diffMV.dy != 0)) 2160c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2170c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1)); 2180c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2190c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2200c1bc742181ded4930842b46e9507372f0b1b963James Dong 2210c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 2220c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2230c1bc742181ded4930842b46e9507372f0b1b963James Dong 2240c1bc742181ded4930842b46e9507372f0b1b963James Dong 2250c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */ 2260c1bc742181ded4930842b46e9507372f0b1b963James Dong 2270c1bc742181ded4930842b46e9507372f0b1b963James Dong 228