⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_avs_dec_decompressor_mc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
//
//              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) 2007 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)

#include "umc_avs_dec_decompressor.h"
#include "umc_avs_dec_pic.h"

namespace UMC
{

static
IppiSize AVSLumaBlockSize[4] =
{
    {16, 16}, {16, 8}, {8, 16}, {8, 8}
};

void AVSDecompressor::CompensateMotionLumaPMacroBlock(void)
{
    // set pointer to the block's beginning
    m_lumaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[0];
    m_lumaMCParams.dstStep = m_recCtx.m_iPitch;

    // set the initial block position
    m_lumaMCParams.pointBlockPos.x = m_recCtx.MbX * 16;
    m_lumaMCParams.pointBlockPos.y = m_recCtx.MbY * 16;

    // select block size
    m_lumaMCParams.sizeBlock = AVSLumaBlockSize[m_pMbInfo->divType];

    switch (m_pMbInfo->divType)
    {
    case Div_16x16:
        CompensateMotionLumaUniDir(0, PredForward);
        break;

    case Div_16x8:
        CompensateMotionLumaUniDir(0, PredForward);

        m_lumaMCParams.pointBlockPos.y += 8;
        m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8;
        CompensateMotionLumaUniDir(2, PredForward);
        break;

    case Div_8x16:
        CompensateMotionLumaUniDir(0, PredForward);

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        CompensateMotionLumaUniDir(1, PredForward);
        break;

    default:
        CompensateMotionLumaUniDir(0, PredForward);

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        CompensateMotionLumaUniDir(1, PredForward);

        m_lumaMCParams.pointBlockPos.x -= 8;
        m_lumaMCParams.pointBlockPos.y += 8;
        m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8 - 8;
        CompensateMotionLumaUniDir(2, PredForward);

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        CompensateMotionLumaUniDir(3, PredForward);
        break;
    }

} // void AVSDecompressor::CompensateMotionLumaPMacroBlock(void)

#define COMPENSATE_MOTION_LUMA(block_num) \
{ \
    eAVSPredType predType; \
    predType = (eAVSPredType) m_pMbInfo->predType[block_num]; \
    if (PredBiDir == predType) \
    { \
        CompensateMotionLumaBiDir(block_num); \
    } \
    else \
    { \
        CompensateMotionLumaUniDir(block_num, predType); \
    } \
}

void AVSDecompressor::CompensateMotionLumaBMacroBlock(void)
{
    // set pointer to the block's beginning
    m_lumaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[0];
    m_lumaMCParams.dstStep = m_recCtx.m_iPitch;

    // set the initial block position
    m_lumaMCParams.pointBlockPos.x = m_recCtx.MbX * 16;
    m_lumaMCParams.pointBlockPos.y = m_recCtx.MbY * 16;

    // select block size
    m_lumaMCParams.sizeBlock = AVSLumaBlockSize[m_pMbInfo->divType];

    switch (m_pMbInfo->divType)
    {
    case Div_16x16:
        COMPENSATE_MOTION_LUMA(0)
        break;

    case Div_16x8:
        COMPENSATE_MOTION_LUMA(0)

        m_lumaMCParams.pointBlockPos.y += 8;
        m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8;
        COMPENSATE_MOTION_LUMA(2)
        break;

    case Div_8x16:
        COMPENSATE_MOTION_LUMA(0)

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        COMPENSATE_MOTION_LUMA(1)
        break;

    default:
        COMPENSATE_MOTION_LUMA(0)

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        COMPENSATE_MOTION_LUMA(1)

        m_lumaMCParams.pointBlockPos.x -= 8;
        m_lumaMCParams.pointBlockPos.y += 8;
        m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8 - 8;
        COMPENSATE_MOTION_LUMA(2)

        m_lumaMCParams.pointBlockPos.x += 8;
        m_lumaMCParams.pDst[0] += 8;
        COMPENSATE_MOTION_LUMA(3)
        break;
    }

} // void AVSDecompressor::CompensateMotionLumaBMacroBlock(void)

void AVSDecompressor::CompensateMotionLumaUniDir(Ipp32s blockNum, eAVSPredType typePred)
{
    Ipp32s refIdx;

    // set the source
    {
        AVSPicture *pRef;

        refIdx = m_pMbInfo->refIdx[typePred - 1][blockNum];
        pRef = m_pRef[typePred - 1][refIdx];
        m_lumaMCParams.pSrc[0] = pRef->m_pPlanes8u[0];
        m_lumaMCParams.srcStep = pRef->m_iPitch;
    }

    // set the vector
    m_lumaMCParams.pointVector = m_pMbInfo->mv[typePred - 1][blockNum];

    // do compensation
    ippiInterpolateLumaBlock_AVS_8u_P1R(&m_lumaMCParams);

    // do weighting
    if (m_pMbInfo->weighting_prediction)
    {
        Ipp32s luma_scale, luma_shift;

        // get weighting parameters
        luma_scale = m_recCtx.m_pSlcHeader->luma_scale[typePred - 1][refIdx];
        luma_shift = m_recCtx.m_pSlcHeader->luma_shift[typePred - 1][refIdx];

        ippiWeightPrediction_AVS_8u_C1R(m_lumaMCParams.pDst[0],
                                        m_lumaMCParams.dstStep,
                                        m_lumaMCParams.pDst[0],
                                        m_lumaMCParams.dstStep,
                                        luma_scale,
                                        luma_shift,
                                        m_lumaMCParams.sizeBlock);
    }

} // void AVSDecompressor::CompensateMotionLumaUniDir(Ipp32s blockNum, eAVSPredType typePred)

void AVSDecompressor::CompensateMotionLumaBiDir(Ipp32s blockNum)
{
    Ipp8u tempBlock[16 * 16 + 16];
    Ipp8u *pFrw, *pBck;
    Ipp32s stepFrw, stepBck;

    //
    // do forward motion compensation
    //

    // zero motion vector - simple reset pointers
    if (0 == m_pMbInfo->mv[AVS_FORWARD][blockNum].scalar)
    {
        Ipp32s refIdx;
        AVSPicture *pRef;

        refIdx = m_pMbInfo->refIdx[AVS_FORWARD][blockNum];
        pRef = m_pRef[AVS_FORWARD][refIdx];
        pFrw = pRef->m_pPlanes8u[0];
        stepFrw = pRef->m_iPitch;

        // calculate offset to a corresponding place in the reference picture
        pFrw += m_lumaMCParams.pDst[0] - m_pPlanes8u[0];

        // do weighting
        if (m_pMbInfo->weighting_prediction)
        {
            Ipp32s luma_scale, luma_shift;

            // get weighting parameters
            luma_scale = m_recCtx.m_pSlcHeader->luma_scale[AVS_FORWARD][refIdx];
            luma_shift = m_recCtx.m_pSlcHeader->luma_shift[AVS_FORWARD][refIdx];

            ippiWeightPrediction_AVS_8u_C1R(pFrw,
                                            stepFrw,
                                            m_lumaMCParams.pDst[0],
                                            m_lumaMCParams.dstStep,
                                            luma_scale,
                                            luma_shift,
                                            m_lumaMCParams.sizeBlock);

            // set the pointer to the block
            pFrw = m_lumaMCParams.pDst[0];
            stepFrw = m_lumaMCParams.dstStep;
        }
    }
    // doing honest compensation
    else
    {
        pFrw = m_lumaMCParams.pDst[0];
        stepFrw = m_lumaMCParams.dstStep;
        CompensateMotionLumaUniDir(blockNum, PredForward);
    }

    //
    // do backward motion compensation
    //

    // zero motion vector - simple reset pointers
    if (0 == m_pMbInfo->mv[AVS_BACKWARD][blockNum].scalar)
    {
        Ipp32s refIdx;
        AVSPicture *pRef;

        refIdx = m_pMbInfo->refIdx[AVS_BACKWARD][blockNum];
        pRef = m_pRef[AVS_BACKWARD][refIdx];
        pBck = pRef->m_pPlanes8u[0];
        stepBck = pRef->m_iPitch;

        // calculate offset to a corresponding place in the reference picture
        pBck += m_lumaMCParams.pDst[0] - m_pPlanes8u[0];

        // do weighting
        if (m_pMbInfo->weighting_prediction)
        {
            Ipp32s luma_scale, luma_shift;

            // get weighting parameters
            luma_scale = m_recCtx.m_pSlcHeader->luma_scale[AVS_BACKWARD][refIdx];
            luma_shift = m_recCtx.m_pSlcHeader->luma_shift[AVS_BACKWARD][refIdx];

            ippiWeightPrediction_AVS_8u_C1R(pBck,
                                            stepBck,
                                            align_pointer<Ipp8u *> (tempBlock, 16),
                                            16,
                                            luma_scale,
                                            luma_shift,
                                            m_lumaMCParams.sizeBlock);

            // set the pointer to the block
            pBck = align_pointer<Ipp8u *> (tempBlock, 16);
            stepBck = 16;
        }
    }
    // doing honest compensation
    else
    {
        Ipp8u *pDstPrev;
        Ipp32s stepPrev;

        // change the destination pointer
        pDstPrev = m_lumaMCParams.pDst[0];
        stepPrev = m_lumaMCParams.dstStep;
        m_lumaMCParams.pDst[0] = align_pointer<Ipp8u *> (tempBlock, 16);
        m_lumaMCParams.dstStep = 16;

        pBck = m_lumaMCParams.pDst[0];
        stepBck = m_lumaMCParams.dstStep;
        CompensateMotionLumaUniDir(blockNum, PredBackward);

        // restore the destination pointer
        m_lumaMCParams.pDst[0] = pDstPrev;
        m_lumaMCParams.dstStep = stepPrev;
    }

    // get average from two directions
    ippiInterpolateBlock_H264_8u_P3P1R(pFrw,
                                       pBck,
                                       m_lumaMCParams.pDst[0],
                                       m_lumaMCParams.sizeBlock.width,
                                       m_lumaMCParams.sizeBlock.height,
                                       stepFrw,
                                       stepBck,
                                       m_lumaMCParams.dstStep);


} // void AVSDecompressor::CompensateMotionLumaBiDir(Ipp32s blockNum)

static
IppiSize AVSChromaBlockSize[2][4] =
{
    // 4:2:0 block sizes
    {
        {8, 8}, {8, 4}, {4, 8}, {4, 4}
    },

    // 4:2:2 block sizes
    {
        {8, 16}, {8, 8}, {4, 16}, {4, 8}
    }
};

void AVSDecompressor::CompensateMotionChromaPMacroBlock(void)
{
    Ipp32s blockHeight;

    // set pointer to the block's beginning
    m_chromaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[1];
    m_chromaMCParams.pDst[1] = m_recCtx.m_pPlanes8u[2];
    m_chromaMCParams.dstStep = m_recCtx.m_iPitch;

    // set the initial block position
    m_chromaMCParams.pointBlockPos.x = m_recCtx.MbX * 8;
    m_chromaMCParams.pointBlockPos.y = m_recCtx.MbY * 8;

    // select block size

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -