📄 umc_h264_mc.cpp
字号:
//// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2004 - 2005 Intel Corporation. All Rights Reserved.//#include <string.h>#include "umc_h264_video_encoder.h"#include "umc_h264_tables.h"// pitch of the prediction buffer which is the destination buffer for the// functions in this file#define DEST_PITCH 16////////////////////////////////////////////////////////////////////////////////// SubpelMVAdjust//// Local inline function which uses the input motion vector to adjust the// reference pointer to the correct full pel position for interpolation.// It sets iXType and iYType vars to for selection of the specific// interpolation type function to use and returns the full pel offset to// be added to the reference pointer. Optimized to avoid computation when not// required.//using namespace UMC_H264_ENCODER;namespace UMC{inline static Ipp32s SubpelMVAdjust( const T_ECORE_MV *pMV, Ipp32u uPitch, Ipp32s& iXType, Ipp32s& iYType){ Ipp32s iXOffset; Ipp32s iYOffset; Ipp32s iPelOffset = 0; // convert 1/4 pel vector to pel vector and interpolation type iXType = 0; // init to no interpolation required iYType = 0; if (pMV->iMVx) { iXOffset = pMV->iMVx / SubPelFactor; iXType = pMV->iMVx - iXOffset*SubPelFactor; if (iXType < 0) { iXOffset -= 1; iXType += SubPelFactor; } iPelOffset += iXOffset; } if (pMV->iMVy) { iYOffset = pMV->iMVy / SubPelFactor; iYType = pMV->iMVy - iYOffset*SubPelFactor; if (iYType < 0) { iYOffset -= 1; iYType += SubPelFactor; } iPelOffset += iYOffset*uPitch; } return iPelOffset;} // SubpelMVAdjust////////////////////////////////////////////////////////////////////////////////// SubpelChromaMVAdjust//// Local inline function which uses the input motion vector to adjust the// reference pointer to the correct full pel position for interpolation.// It sets iXType and iYType vars to for selection of the specific// interpolation type function to use and returns the full pel offset to// be added to the reference pointer. Optimized to avoid computation when not// required.//////////////////////////////////////////////////////////////////////////////////inline static Ipp32s SubpelChromaMVAdjust( const T_ECORE_MV *pMV, Ipp32u uPitch, Ipp32s& iXType, Ipp32s& iYType){ Ipp32s iXOffset; Ipp32s iYOffset; Ipp32s iPelOffset = 0; const Ipp32s ChromaSubPelFactor = 2 * SubPelFactor; // convert 1/8 pel vector to pel vector and interpolation type iXType = 0; // init to no interpolation required iYType = 0; if (pMV->iMVx) { iXOffset = pMV->iMVx / ChromaSubPelFactor; iXType = pMV->iMVx - iXOffset*ChromaSubPelFactor; if (iXType < 0) { iXOffset -= 1; iXType += ChromaSubPelFactor; } iPelOffset += iXOffset; } if (pMV->iMVy) { iYOffset = pMV->iMVy / ChromaSubPelFactor; iYType = pMV->iMVy - iYOffset*ChromaSubPelFactor; if (iYType < 0) { iYOffset -= 1; iYType += ChromaSubPelFactor; } iPelOffset += iYOffset*uPitch; } return iPelOffset;} // SubpelChromaMVAdjust////////////////////////////////////////////////////////////////////////////////// MCOneMBLuma//// Copy all 16 4x4 luma blocks from reference source using the input motion// vectors to locate and compute the reference pels using interpolation as// required. The vectors are in subpel units. Results are stored in the output// buffer as a 16x16 block with a row pitch of DEST_PITCH.//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::MCOneMBLuma( Ipp32u uMB, Ipp32u uPitch, // pitch of source data const T_ECORE_MV *pMVFwd, // motion vectors in subpel units const T_ECORE_MV *pMVBwd, // motion vectors in subpel units Ipp8u* pDst, // put the resulting block here T_EncodeMBData *pMBData // Pointer to MB Data){ Ipp32u uBlock, uRow; Ipp32s iXType; Ipp32s iYType; const Ipp8u *pMCRef; Ipp8u *pMCDst; const T_ECORE_MV *pMCMV; Ipp8u* pBiPred; MB_Type uMBType = pMBData->uMBType; // type of MB Ipp32s uMVOffset = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex; T_RefIdx *pRefIdxL0 = &m_pCurrentFrame->pRefIdxL0[uMVOffset]; T_RefIdx *pRefIdxL1 = &m_pCurrentFrame->pRefIdxL1[uMVOffset]; H264EncoderFrame **pRefPicList0 = m_pCurrentFrame->GetRefPicList(0, LIST_0)->m_RefPicList; H264EncoderFrame **pRefPicList1 = m_pCurrentFrame->GetRefPicList(0, LIST_1)->m_RefPicList; Ipp32u uOffset = m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift; T_RefIdx block_ref; Ipp8u * prev_frame = 0; Ipp8u * futr_frame = 0; switch (uMBType) { case MBTYPE_DIRECT: { // Copy the stored 16x16 prediction data from the Direct Mode Buffer Ipp32u uRow; Ipp8u* pDirect = m_pCurrentFrame->pPred4DirectB; pMCDst = pDst; for (uRow=0; uRow<16; uRow++) { memcpy(pMCDst, pDirect, 16); pMCDst += DEST_PITCH; pDirect += 16; } } break; case MBTYPE_BIDIR: case MBTYPE_BIDIR_BIDIR_16x8: case MBTYPE_BIDIR_BIDIR_8x16: // Copy the stored 16x16 prediction data from the BiPred Mode Buffer pBiPred = m_pCurrentFrame->pPred4BiPred; pMCDst = pDst; for (uRow=0; uRow<16; uRow++) { memcpy(pMCDst, pBiPred, 16); pMCDst += DEST_PITCH; pBiPred += 16; } break; case MBTYPE_INTER: case MBTYPE_FORWARD: // 1 vector for the MB // convert 1/4 pel vector to pel vector and interpolation type block_ref = pRefIdxL0[0]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset; prev_frame += SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x16 block ippiInterpolateLuma_H264_8u_C1R(prev_frame, uPitch, pDst, 16, iXType, iYType, size16x16); break; case MBTYPE_BACKWARD: // 1 vector for the MB // convert 1/4 pel vector to pel vector and interpolation type block_ref = pRefIdxL1[0]; futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset; futr_frame += SubpelMVAdjust(pMVBwd, uPitch, iXType, iYType); // interpolate copy the 16x16 block ippiInterpolateLuma_H264_8u_C1R(futr_frame, uPitch,pDst, 16, iXType, iYType, size16x16); break; case MBTYPE_INTER_16x8: case MBTYPE_FWD_FWD_16x8: // 2 vectors for the MB block_ref = pRefIdxL0[0]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); // Do other 16x8 block pMVFwd += uWidthIn4x4Blocks*2; // Reposition MV pointer to next 16x8 pDst += DEST_PITCH*8; block_ref = pRefIdxL0[uWidthIn4x4Blocks * 2]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset + uPitch*8; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); break; case MBTYPE_FWD_BWD_16x8: // 2 vectors for the MB block_ref = pRefIdxL0[0]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); // Do other 16x8 block pMVBwd += uWidthIn4x4Blocks*2; // Reposition MV pointer to next 16x8 pDst += DEST_PITCH*8; block_ref = pRefIdxL1[uWidthIn4x4Blocks * 2]; futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset + uPitch*8; pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); break; case MBTYPE_BWD_FWD_16x8: // 2 vectors for the MB block_ref = pRefIdxL1[0]; futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset; pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); // Do other 16x8 block pMVFwd += uWidthIn4x4Blocks * 2; // Reposition MV pointer to next 16x8 pDst += DEST_PITCH*8; block_ref = pRefIdxL0[uWidthIn4x4Blocks * 2]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset + uPitch*8; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); break; case MBTYPE_BWD_BWD_16x8: // 2 vectors for the MB block_ref = pRefIdxL1[0]; futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset; pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); // Do other 16x8 block pMVBwd += uWidthIn4x4Blocks * 2; // Reposition MV pointer to next 16x8 pDst += DEST_PITCH*8; block_ref = pRefIdxL1[uWidthIn4x4Blocks * 2]; futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset + uPitch*8; pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); break; case MBTYPE_BIDIR_FWD_16x8: // Copy the stored 16x8 prediction data from the BiPred Mode Buffer pBiPred = m_pCurrentFrame->pPred4BiPred; pMCDst = pDst; for (uRow=0; uRow<8; uRow++) { memcpy(pMCDst, pBiPred, 16); pMCDst += DEST_PITCH; pBiPred += 16; } // Do other 16x8 block pMVFwd += uWidthIn4x4Blocks*2; // Reposition MV pointer to next 16x8 pDst += DEST_PITCH*8; block_ref = pRefIdxL0[uWidthIn4x4Blocks * 2]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset + uPitch*8; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8); break; case MBTYPE_FWD_BIDIR_16x8: // 2 vectors for the MB block_ref = pRefIdxL0[0]; prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset; pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, uPitch, iXType, iYType); // interpolate copy the 16x8 block ippiInterpolateLuma_H264_8u_C1R(pMCRef, uPitch,pDst, 16, iXType, iYType, size16x8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -