📄 umc_mpeg2_dec_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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG2_VIDEO_DECODER)
#include "umc_mpeg2_dec_base.h"
#pragma warning(disable: 4244)
using namespace UMC;
/****************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#define DEF_COPY_HP(NAME) \
extern void NAME(const Ipp8u* pSrc, Ipp32s srcStep, Ipp8u* pDst, Ipp32s dstStep)
#ifdef __cplusplus
} /* extern "C" */
#endif
/****************************************************************/
Ipp16s zero_memory[64*8] = {0};
#define MC_FORWARD0(H, PITCH_L, PITCH_C) \
Ipp32s prev_index = frame_buffer.prev_index; \
Ipp32s curr_index = frame_buffer.curr_index; \
Ipp8u *ref_Y_data = frame_buffer.frame_p_c_n[prev_index].Y_comp_data; \
Ipp8u *ref_U_data = frame_buffer.frame_p_c_n[prev_index].U_comp_data; \
Ipp8u *ref_V_data = frame_buffer.frame_p_c_n[prev_index].V_comp_data; \
Ipp8u *cur_Y_data = frame_buffer.frame_p_c_n[curr_index].Y_comp_data; \
Ipp8u *cur_U_data = frame_buffer.frame_p_c_n[curr_index].U_comp_data; \
Ipp8u *cur_V_data = frame_buffer.frame_p_c_n[curr_index].V_comp_data; \
Ipp32s offset_l = video->offset_l; \
Ipp32s offset_c = video->offset_c; \
ippiCopy16x16_8u_C1R(ref_Y_data + offset_l, PITCH_L, cur_Y_data + offset_l, PITCH_L); \
ippiCopy8x##H##_8u_C1R(ref_U_data + offset_c, PITCH_C, cur_U_data + offset_c, PITCH_C); \
ippiCopy8x##H##_8u_C1R(ref_V_data + offset_c, PITCH_C, cur_V_data + offset_c, PITCH_C);
void MPEG2VideoDecoderBase::mc_frame_forward0_420(IppVideoContext *video)
{
MC_FORWARD0(8, frame_buffer.Y_comp_pitch, frame_buffer.U_comp_pitch);
}
void MPEG2VideoDecoderBase::mc_frame_forward0_422(IppVideoContext *video)
{
MC_FORWARD0(16, frame_buffer.Y_comp_pitch, frame_buffer.U_comp_pitch);
}
void MPEG2VideoDecoderBase::mc_field_forward0_420(IppVideoContext *video)
{
MC_FORWARD0(8, 2 * frame_buffer.Y_comp_pitch, 2 * frame_buffer.U_comp_pitch);
}
void MPEG2VideoDecoderBase::mc_field_forward0_422(IppVideoContext *video)
{
MC_FORWARD0(16, 2 * frame_buffer.Y_comp_pitch, 2 * frame_buffer.U_comp_pitch);
}
#define buffFRW prev_index
#define buffBKW next_index
#define indexFRW 0
#define indexBKW 2
#define FUNC_MC_MBLOCK_420(DIR, METH, FLG) \
Ipp8u *refY = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].Y_comp_data; \
Ipp8u *refU = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].U_comp_data; \
Ipp8u *refV = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].V_comp_data; \
Ipp8u *curY = video->blkCurrYUV[0]; \
Ipp8u *curU = video->blkCurrYUV[1]; \
Ipp8u *curV = video->blkCurrYUV[2]; \
Ipp32s pitch_l = frame_buffer.Y_comp_pitch; \
Ipp32s pitch_c = frame_buffer.U_comp_pitch; \
Ipp32s flag_l, flag_c; \
Ipp32s offs_l, offs_c; \
Ipp16s vec_x, vec_y; \
\
if(video->prediction_type == IPPVC_MC_FRAME) \
{ \
DECODE_MV(video->bs, index##DIR, index##DIR, vec_x, vec_y); \
video->PMV[index##DIR + 4] = video->PMV[index##DIR]; \
video->PMV[index##DIR + 5] = video->PMV[index##DIR + 1]; \
\
CALC_OFFSETS_FRAME_420(offs_l, offs_c, flag_l, flag_c, vec_x, vec_y, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec_x&1), pitch_l, 16+(vec_y&1)) \
\
FUNC_##METH##_HP(16, 16, refY + offs_l, pitch_l, curY, pitch_l, flag_l, 0); \
FUNC_##METH##_HP(8, 8, refU + offs_c, pitch_c, curU, pitch_c, flag_c, 0); \
FUNC_##METH##_HP(8, 8, refV + offs_c, pitch_c, curV, pitch_c, flag_c, 0); \
} \
else \
{ \
Ipp32s pitch_l2 = pitch_l + pitch_l; \
Ipp32s pitch_c2 = pitch_c + pitch_c; \
Ipp32s field_sel0, field_sel1; \
Ipp16s vec1_x, vec1_y; \
\
GET_1BIT(video->bs, field_sel0); \
DECODE_MV_FIELD(video->bs, index##DIR, index##DIR, vec_x, vec_y); \
GET_1BIT(video->bs, field_sel1); \
DECODE_MV_FIELD(video->bs, index##DIR + 4, index##DIR, vec1_x, vec1_y); \
\
CALC_OFFSETS_FIELD_420(offs_l, offs_c, flag_l, flag_c, vec_x, vec_y, field_sel0, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec_x&1), pitch_l2, 8+(vec_y&1)) \
\
FUNC_##METH##_HP(16, 8, refY + offs_l, pitch_l2, curY, pitch_l2, flag_l, 0); \
FUNC_##METH##_HP(8, 4, refU + offs_c, pitch_c2, curU, pitch_c2, flag_c, 0); \
FUNC_##METH##_HP(8, 4, refV + offs_c, pitch_c2, curV, pitch_c2, flag_c, 0); \
\
CALC_OFFSETS_FIELD_420(offs_l, offs_c, flag_l, flag_c, vec1_x, vec1_y, field_sel1, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec1_x&1), pitch_l2, 8+(vec1_y&1)) \
\
FUNC_##METH##_HP(16, 8, refY + offs_l, pitch_l2, curY + pitch_l, pitch_l2, flag_l, 0); \
FUNC_##METH##_HP(8, 4, refU + offs_c, pitch_c2, curU + pitch_c, pitch_c2, flag_c, 0); \
FUNC_##METH##_HP(8, 4, refV + offs_c, pitch_c2, curV + pitch_c, pitch_c2, flag_c, 0); \
} \
return UMC_OK
Status MPEG2VideoDecoderBase::mc_frame_forward_420(IppVideoContext *video)
{
FUNC_MC_MBLOCK_420(FRW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_frame_backward_420(IppVideoContext *video)
{
FUNC_MC_MBLOCK_420(BKW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_frame_backward_add_420(IppVideoContext *video)
{
FUNC_MC_MBLOCK_420(BKW, AVE, AV);
}
#define FUNC_MC_MBLOCK_422(DIR, METH, FLG) \
Ipp8u *refY = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].Y_comp_data; \
Ipp8u *refU = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].U_comp_data; \
Ipp8u *refV = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].V_comp_data; \
Ipp8u *curY = video->blkCurrYUV[0]; \
Ipp8u *curU = video->blkCurrYUV[1]; \
Ipp8u *curV = video->blkCurrYUV[2]; \
Ipp32s pitch_l = frame_buffer.Y_comp_pitch; \
Ipp32s pitch_c = frame_buffer.U_comp_pitch; \
Ipp32s flag_l, flag_c; \
Ipp32s offs_l, offs_c; \
Ipp16s vec_x, vec_y; \
\
if(video->prediction_type == IPPVC_MC_FRAME) \
{ \
DECODE_MV(video->bs, index##DIR, index##DIR, vec_x, vec_y); \
video->PMV[index##DIR + 4] = video->PMV[index##DIR]; \
video->PMV[index##DIR + 5] = video->PMV[index##DIR + 1]; \
\
CALC_OFFSETS_FRAME_422(offs_l, offs_c, flag_l, flag_c, vec_x, vec_y, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec_x&1), pitch_l, 16+(vec_y&1)) \
\
FUNC_##METH##_HP(16, 16, refY + offs_l, pitch_l, curY, pitch_l, flag_l, 0); \
FUNC_##METH##_HP(8, 16, refU + offs_c, pitch_c, curU, pitch_c, flag_c, 0); \
FUNC_##METH##_HP(8, 16, refV + offs_c, pitch_c, curV, pitch_c, flag_c, 0); \
} \
else \
{ \
Ipp32s pitch_l2 = pitch_l + pitch_l; \
Ipp32s pitch_c2 = pitch_c + pitch_c; \
Ipp32s field_sel0, field_sel1; \
Ipp16s vec1_x, vec1_y; \
\
GET_1BIT(video->bs, field_sel0); \
DECODE_MV_FIELD(video->bs, index##DIR, index##DIR, vec_x, vec_y); \
GET_1BIT(video->bs, field_sel1); \
DECODE_MV_FIELD(video->bs, index##DIR + 4, index##DIR, vec1_x, vec1_y); \
\
CALC_OFFSETS_FIELD_422(offs_l, offs_c, flag_l, flag_c, vec_x, vec_y, field_sel0, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec_x&1), pitch_l2, 8+(vec_y&1)) \
\
FUNC_##METH##_HP(16, 8, refY + offs_l, pitch_l2, curY, pitch_l2, flag_l, 0); \
FUNC_##METH##_HP(8, 8, refU + offs_c, pitch_c2, curU, pitch_c2, flag_c, 0); \
FUNC_##METH##_HP(8, 8, refV + offs_c, pitch_c2, curV, pitch_c2, flag_c, 0); \
\
CALC_OFFSETS_FIELD_422(offs_l, offs_c, flag_l, flag_c, vec1_x, vec1_y, field_sel1, HP_FLAG_##FLG) \
CHECK_OFFSET_L(offs_l+(vec1_x&1), pitch_l2, 8+(vec1_y&1)) \
\
FUNC_##METH##_HP(16, 8, refY + offs_l, pitch_l2, curY + pitch_l, pitch_l2, flag_l, 0); \
FUNC_##METH##_HP(8, 8, refU + offs_c, pitch_c2, curU + pitch_c, pitch_c2, flag_c, 0); \
FUNC_##METH##_HP(8, 8, refV + offs_c, pitch_c2, curV + pitch_c, pitch_c2, flag_c, 0); \
} \
return UMC_OK
Status MPEG2VideoDecoderBase::mc_frame_forward_422(IppVideoContext *video)
{
FUNC_MC_MBLOCK_422(FRW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_frame_backward_422(IppVideoContext *video)
{
FUNC_MC_MBLOCK_422(BKW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_frame_backward_add_422(IppVideoContext *video)
{
FUNC_MC_MBLOCK_422(BKW, AVE, AV);
}
#define FUNC_MC_FULLPEL(DIR, METH, FLG) \
Ipp8u *refY = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].Y_comp_data; \
Ipp8u *refU = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].U_comp_data; \
Ipp8u *refV = frame_buffer.frame_p_c_n[frame_buffer.buff##DIR].V_comp_data; \
Ipp8u *curY = video->blkCurrYUV[0]; \
Ipp8u *curU = video->blkCurrYUV[1]; \
Ipp8u *curV = video->blkCurrYUV[2]; \
Ipp32s pitch_l = frame_buffer.Y_comp_pitch; \
Ipp32s pitch_c = frame_buffer.U_comp_pitch; \
Ipp32s offs_l, offs_c; \
Ipp16s vec_x, vec_y; \
\
DECODE_MV_FULLPEL(video->bs, index##DIR, index##DIR, vec_x, vec_y); \
\
CALC_OFFSETS_FULLPEL(offs_l, offs_c, vec_x, vec_y, pitch_l, pitch_c) \
CHECK_OFFSET_L(offs_l, pitch_l, 16) \
\
FUNC_##METH##_HP(16, 16, refY + offs_l, pitch_l, curY, pitch_l, 0, 0); \
FUNC_##METH##_HP(8, 8, refU + offs_c, pitch_c, curU, pitch_c, 0, 0); \
FUNC_##METH##_HP(8, 8, refV + offs_c, pitch_c, curV, pitch_c, 0, 0); \
\
return UMC_OK
Status MPEG2VideoDecoderBase::mc_fullpel_forward(IppVideoContext *video)
{
FUNC_MC_FULLPEL(FRW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_fullpel_backward(IppVideoContext *video)
{
FUNC_MC_FULLPEL(BKW, COPY, CP);
}
Status MPEG2VideoDecoderBase::mc_fullpel_backward_add(IppVideoContext *video)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -