📄 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 - 2007 Intel Corporation. All Rights Reserved.
//
#include <string.h>
#include "umc_h264_video_encoder.h"
#include "umc_h264_tables.h"
#include "umc_h264_bme.h"
// pitch of the prediction buffer which is the destination buffer for the
// functions in this file
#define DEST_PITCH 16
namespace UMC_H264_ENCODER
{
////////////////////////////////////////////////////////////////////////////////
// C_DirectB_PredictOneMB_Cr
//
// Predict chroma values of current direct B mode macroblock by interpolating
// from previous and future references.
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType>
inline void DirectB_PredictOneMB_Cr(
PixType *const pDirB, // pointer to current direct mode MB buffer
const PixType *const pPrev, // pointer to previous ref plane buffer
const PixType *const pFutr, // pointer to future ref plane buffer
const Ipp32s pitchPixels, // reference buffers pitch in pixels
const Ipp32u uInterpType,// 0 = Skip, 1 = Default, 2 = Implicit Weighted
const Ipp32s W0,
const Ipp32s W1,
const IppiSize & roiSize
)
{
if (!uInterpType)
{
for (Ipp32s i = 0, k = 0; i < roiSize.height; i ++, k += pitchPixels)
memcpy(pDirB + i * 16, pPrev + k, roiSize.width * sizeof(PixType));
}
else if (uInterpType == 1)
{
ippiInterpolateBlock_H264(pPrev, pFutr,
pDirB, roiSize.width, roiSize.height, pitchPixels*sizeof(PixType));
} else {
for (Ipp32s i = 0, k = 0; i < roiSize.height; i ++, k += pitchPixels)
for (Ipp32s j = 0; j < roiSize.width; j ++)
{
pDirB[i * 16 + j] = (PixType) ((pPrev[k + j] * W0 + pFutr[k + j] * W1 + 32) >> 6);
}
}
} // C_DirectB_PredictOneMB_Cr
template <class PixType>
inline void GetImplicitBidirPred(
PixType *const pDirB, // pointer to current direct mode MB buffer
const PixType *const pPrev, // pointer to previous ref plane buffer
const PixType *const pFutr, // pointer to future ref plane buffer
const Ipp32u pitchPixels, // reference buffers pitch in pixels
const IppiSize & roiSize
)
{
ippiInterpolateBlock_H264(pPrev, pFutr,
pDirB, roiSize.width, roiSize.height, pitchPixels*sizeof(PixType));
} // C_DirectB_PredictOneMB_Cr
////////////////////////////////////////////////////////////////////////////////
// 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.
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType> void H264CoreEncoder<PixType,CoeffsType>::MCOneMBLuma(
H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
Ipp32u uMB,
Ipp32s pitchPixels, // pitch of source data in pixels
const H264MotionVector *pMVFwd, // motion vectors in subpel units
const H264MotionVector *pMVBwd, // motion vectors in subpel units
PixType* pDst // put the resulting block here
)
{
Ipp32u uBlock, uRow;
Ipp32s iXType;
Ipp32s iYType;
const PixType *pMCRef;
PixType *pMCDst;
const H264MotionVector *pMCMV;
PixType* pBiPred;
H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
Ipp32s is_cur_mb_field = curr_slice->m_is_cur_mb_field;
MB_Type uMBType = static_cast<MB_Type>(cur_mb.GlobalMacroblockInfo->mbtype); // type of MB
#ifdef NEW_INTERPOLATE
Ipp32s mb_decoding_flag = pGetMBFieldDecodingFlag(curr_slice->cur_mb.GlobalMacroblockInfo);
#endif // NEW_INTERPOLATE
T_RefIdx *pRefIdxL0 = cur_mb.RefIdxs[LIST_0]->RefIdxs;
T_RefIdx *pRefIdxL1 = cur_mb.RefIdxs[LIST_1]->RefIdxs;
H264EncoderFrame<PixType> **pRefPicList0 = GetRefPicList(curr_slice, LIST_0,is_cur_mb_field,uMB&1)->m_RefPicList;
H264EncoderFrame<PixType> **pRefPicList1 = GetRefPicList(curr_slice, LIST_1,is_cur_mb_field,uMB&1)->m_RefPicList;
Ipp8s *pFields0 = GetRefPicList(curr_slice, LIST_0,is_cur_mb_field,uMB&1)->m_Prediction;
Ipp8s *pFields1 = GetRefPicList(curr_slice, LIST_1,is_cur_mb_field,uMB&1)->m_Prediction;
Ipp32u uOffset = m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field];
T_RefIdx block_ref;
PixType * prev_frame = 0;
PixType * futr_frame = 0;
#ifdef NEW_INTERPOLATE
Ipp32s uMBy = curr_slice->m_CurMB_Y*16;
#endif
switch (uMBType)
{
case MBTYPE_DIRECT: {
// Copy the stored 16x16 prediction data from the Direct Mode Buffer
Ipp32u uRow;
PixType* pDirect = curr_slice->m_pPred4DirectB;
pMCDst = pDst;
for (uRow=0; uRow<16; uRow++) {
memcpy(pMCDst, pDirect, 16*sizeof(PixType));
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 = curr_slice->m_pPred4BiPred;
pMCDst = pDst;
for (uRow=0; uRow<16; uRow++) {
memcpy(pMCDst, pBiPred, 16*sizeof(PixType));
pMCDst += DEST_PITCH;
pBiPred += 16;
}
break;
case MBTYPE_INTER:
case MBTYPE_SKIPPED:
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
+ curr_slice->m_InitialOffset[pFields0[block_ref]];
prev_frame += SubpelMVAdjust(pMVFwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x16 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, prev_frame, pitchPixels, pDst, 16, iXType, iYType, size16x16, pMVFwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(prev_frame, pitchPixels*sizeof(PixType), pDst, sizeof(PixType)*16, iXType, iYType, size16x16, m_PicParamSet.bit_depth_luma);
#endif
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
+ curr_slice->m_InitialOffset[pFields1[block_ref]];
futr_frame += SubpelMVAdjust(pMVBwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x16 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, futr_frame, pitchPixels, pDst, 16, iXType, iYType, size16x16, pMVBwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(futr_frame, pitchPixels*sizeof(PixType), pDst, sizeof(PixType)*16, iXType, iYType, size16x16, m_PicParamSet.bit_depth_luma);
#endif
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
+ curr_slice->m_InitialOffset[pFields0[block_ref]];
pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVFwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
// Do other 16x8 block
pMVFwd += 4*2; // Reposition MV pointer to next 16x8
pDst += DEST_PITCH*8;
block_ref = pRefIdxL0[4 * 2];
prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields0[block_ref]] + pitchPixels*8;
pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVFwd->mvy, uMBy, 8);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
break;
case MBTYPE_FWD_BWD_16x8:
// 2 vectors for the MB
block_ref = pRefIdxL0[0];
prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields0[block_ref]];
pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVFwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
// Do other 16x8 block
pMVBwd += 4*2; // Reposition MV pointer to next 16x8
pDst += DEST_PITCH*8;
block_ref = pRefIdxL1[4 * 2];
futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields1[block_ref]] + pitchPixels*8;
pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVBwd->mvy, uMBy, 8);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
break;
case MBTYPE_BWD_FWD_16x8:
// 2 vectors for the MB
block_ref = pRefIdxL1[0];
futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields1[block_ref]];
pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVBwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
// Do other 16x8 block
pMVFwd += 4 * 2; // Reposition MV pointer to next 16x8
pDst += DEST_PITCH*8;
block_ref = pRefIdxL0[4 * 2];
prev_frame = pRefPicList0[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields0[block_ref]] + pitchPixels*8;
pMCRef = prev_frame + SubpelMVAdjust(pMVFwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVFwd->mvy, uMBy, 8);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
break;
case MBTYPE_BWD_BWD_16x8:
// 2 vectors for the MB
block_ref = pRefIdxL1[0];
futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields1[block_ref]];
pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVBwd->mvy, uMBy, 0);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
// Do other 16x8 block
pMVBwd += 4 * 2; // Reposition MV pointer to next 16x8
pDst += DEST_PITCH*8;
block_ref = pRefIdxL1[4 * 2];
futr_frame = pRefPicList1[block_ref]->m_pYPlane + uOffset
+ curr_slice->m_InitialOffset[pFields1[block_ref]] + pitchPixels*8;
pMCRef = futr_frame + SubpelMVAdjust(pMVBwd, pitchPixels, iXType, iYType);
// interpolate copy the 16x8 block
#ifdef NEW_INTERPOLATE
Interpolate(mb_decoding_flag, pMCRef, pitchPixels,pDst, 16, iXType, iYType, size16x8, pMVBwd->mvy, uMBy, 8);
#else
ippiInterpolateLuma_H264(pMCRef, pitchPixels*sizeof(PixType),pDst, sizeof(PixType)*16, iXType, iYType, size16x8, m_PicParamSet.bit_depth_luma);
#endif
break;
case MBTYPE_BIDIR_FWD_16x8:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -