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

📄 umc_h264_segment_decoder_decode_mb.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
//
//              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_H264_VIDEO_DECODER)

#include "umc_h264_segment_decoder.h"
#include "umc_h264_dec.h"
#include "umc_h264_bitstream_inlines.h"
#include "vm_debug.h"

namespace UMC
{

// 0 1 4 5
// 2 3 6 7
// 8 9 c d
// a b e f

const
Ipp8u block2lin[16] =
{
     0, 1, 4, 5,
     2, 3, 6, 7,
     8, 9,12,13,
     10,11,14,15
};

void H264SegmentDecoder::ComputeMotionVectorPredictors(const Ipp8u ListNum,
                                                       Ipp8s RefIndex, // reference index for this part
                                                       const Ipp32s block, // block or subblock number, depending on mbtype
                                                       Ipp32s *pMVx, // resulting MV predictors
                                                       Ipp32s *pMVy)
{
    Ipp32s  px0, px1, px2;
    Ipp32s  py0, py1, py2;
    //    Ipp32s     diff;
    Ipp32s  isRightUnavailable=false;
    // Indicates whether the (above) right block, subblock or
    // macroblock can be used for motion vector prediction.
    // This is not a true boolean, in that we use bitwise operations
    // so that any non-zero value, not just the value true,
    // is considered true.
    Ipp32s  isLeftUnavailable=false;
    // Indicates whether the (above) left block, subblock or
    // macroblock can be used for motion vector prediction.
    // Only used when isRightUnavailable is non-zero.

    H264DecoderMotionVector *sl; // pointer to sb to the left
    H264DecoderMotionVector *sa; // pointer to sb above
    H264DecoderMotionVector *sr; // pointer to sb above right
    Ipp8s *pRefIxl;                    // pointer to corresponding RefIndex sb
    Ipp8s *pRefIxa;
    Ipp8s *pRefIxr;
    H264DecoderMotionVector *sonly = NULL; // pointer to only MV this ref
    H264DecoderMotionVector null = {0,0};
    Ipp8s nullRefIx = -1;
    Ipp32u uSameRefPicCount = 3;
    // To code the rule that if only one of the three reference MV is to
    // the same reference picture as the MV being computed, then that one
    // MV is used as the MV predictor. Initialize to all same, then decrement
    // as "different reference picture" are found.
    H264DecoderBlockLocation Left={-1,-1},Top={-1,-1},TopRight={-1,-1},TopLeft={-1,-1};
    H264DecoderMacroblockMVs *MVs;
    H264DecoderMacroblockRefIdxs *RefIdxs;
    H264DecoderMacroblockGlobalInfo *gmbs;
    MVs = m_gmbinfo->MV[ListNum];
    RefIdxs = m_gmbinfo->RefIdxs[ListNum];
    gmbs = m_gmbinfo->mbs;
    if (m_pSliceHeader->MbaffFrameFlag)
    {
        Ipp32u lbls=0, lbrs=0, tbls=0, tbrs=0, rbls=0, rbrs=0;
        switch (m_cur_mb.GlobalMacroblockInfo->mbtype)
        {
        case MBTYPE_FORWARD:
        case MBTYPE_BACKWARD:
        case MBTYPE_BIDIR:
        case MBTYPE_SKIPPED:
            VM_ASSERT(block == 0);

            Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
            Top = m_cur_mb.CurrentBlockNeighbours.mb_above;
            TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
            TopLeft= m_cur_mb.CurrentBlockNeighbours.mb_above_left;

            isRightUnavailable = (TopRight.mb_num<0);
            isLeftUnavailable = (TopLeft.mb_num<0);

            break;
        case MBTYPE_INTER_16x8:
            VM_ASSERT(block >= 0 && block <= 1);
            // First check for availability of directional predictor which is
            // just used if available.
            if (block == 0)
            {
                // upper half, use predictor from above
                Top= m_cur_mb.CurrentBlockNeighbours.mb_above;
                if (Top.mb_num>=0)
                {
                    tbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))>0;
                    tbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))<0;

                    if (IS_INTER_MBTYPE(gmbs[Top.mb_num].mbtype) &&
                        (((RefIdxs[Top.mb_num].RefIdxs[Top.block_num]<<tbls)>>tbrs) == RefIndex))
                    {
                        *pMVx = MVs[Top.mb_num].MotionVectors[Top.block_num].mvx;
                        *pMVy = ((MVs[Top.mb_num].MotionVectors[Top.block_num].mvy+((MVs[Top.mb_num].MotionVectors[Top.block_num].mvy<0)&&tbls))<<tbrs)>>tbls;
                        return;
                    }
                    else
                    {
                        goto median16x8_0_aff;
                    }
                }
                else
                {
median16x8_0_aff:
                    Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
                    TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
                    TopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left;

                    // init vars for median prediction
                    isRightUnavailable = (TopRight.mb_num<0);
                    if (isRightUnavailable)
                        isLeftUnavailable = (TopLeft.mb_num<0);
                }
            }
            else
            {
                Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[2];
                // lower half, use predictor from left
                if ( Left.mb_num>=0)
                {
                    lbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))>0;
                    lbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))<0;

                    if (IS_INTER_MBTYPE(gmbs[Left.mb_num].mbtype) &&
                        (((RefIdxs[Left.mb_num].RefIdxs[Left.block_num]<<lbls)>>lbrs) == RefIndex))
                    {
                        *pMVx = MVs[Left.mb_num].MotionVectors[Left.block_num].mvx;
                        *pMVy = ((MVs[Left.mb_num].MotionVectors[Left.block_num].mvy+((MVs[Left.mb_num].MotionVectors[Left.block_num].mvy<0)&&lbls))<<lbrs)>>lbls;
                        return;
                    }
                    else
                    {
                        goto median_16x8_1_aff;
                    }
                }
                else
                {
median_16x8_1_aff:

                    Top.mb_num = m_CurMBAddr;
                    Top.block_num = 4;

                    TopLeft.block_num = 8;
                    GetTopLeftLocationForCurrentMBLumaMBAFF(&TopLeft);

                    // init vars for median prediction
                    isRightUnavailable = 1;
                    isLeftUnavailable = (Left.mb_num<0);
                }
            }
            break;
        case MBTYPE_INTER_8x16:
            VM_ASSERT(block >= 0 && block <= 1);
            // First check for availability of directional predictor which is
            // just used if available.
            if (block == 0)
            {
                // left half, use predictor from left
                //LeftBlockNum = block;
                //LeftMB=GetLeftBlock(pMBInfo,LeftBlockNum);
                Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
                if (Left.mb_num>=0)
                {
                    lbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))>0;
                    lbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))<0;
                    if (IS_INTER_MBTYPE(gmbs[Left.mb_num].mbtype) &&
                        (((RefIdxs[Left.mb_num].RefIdxs[Left.block_num]<<lbls)>>lbrs) == RefIndex))
                    {
                        *pMVx = MVs[Left.mb_num].MotionVectors[Left.block_num].mvx;
                        *pMVy = ((MVs[Left.mb_num].MotionVectors[Left.block_num].mvy+((MVs[Left.mb_num].MotionVectors[Left.block_num].mvy<0)&&lbls))<<lbrs)>>lbls;
                        return;
                    }
                    else
                    {
                        goto median_8x16_0_aff;
                    }
                }
                else
                {
median_8x16_0_aff:
                    /*                TopBlockNum=0;
                    TopLeftBlockNum=0;
                    TopRightBlockNum=1;

                    TopMB=GetTopBlock(pMBInfo,TopBlockNum);
                    TopLeftMB=GetTopLeftBlock(pMBInfo,TopLeftBlockNum);
                    TopRightMB=GetTopRightBlock(pMBInfo,TopRightBlockNum);*/

                    Top = m_cur_mb.CurrentBlockNeighbours.mb_above;
                    TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above;
                    TopLeft= m_cur_mb.CurrentBlockNeighbours.mb_above_left;
                    TopRight.block_num+=2;
                    // init vars for median prediction
                    isRightUnavailable = (Top.mb_num<0);
                    if (isRightUnavailable)
                        isLeftUnavailable = (TopLeft.mb_num<0);
                }
            }
            else
            {
                // right half, use predictor from above right unless unavailable,
                // then try above left
                //TopRightBlockNum=3;
                //TopRightMB=GetTopRightBlock(pMBInfo,TopRightBlockNum);
                //TopBlockNum=2;
                //TopMB=GetTopBlock(pMBInfo,TopBlockNum);
                TopRight= m_cur_mb.CurrentBlockNeighbours.mb_above_right;
                Top= m_cur_mb.CurrentBlockNeighbours.mb_above;
                Top.block_num+=2;

                if ( TopRight.mb_num>=0)
                {
                    rbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))>0;
                    rbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))<0;

                    if (IS_INTER_MBTYPE(gmbs[TopRight.mb_num].mbtype) &&
                        (((RefIdxs[TopRight.mb_num].RefIdxs[TopRight.block_num]<<rbls)>>rbrs) == RefIndex))
                    {
                        *pMVx = MVs[TopRight.mb_num].MotionVectors[TopRight.block_num].mvx;
                        *pMVy = ((MVs[TopRight.mb_num].MotionVectors[TopRight.block_num].mvy+((MVs[TopRight.mb_num].MotionVectors[TopRight.block_num].mvy<0)&&rbls))<<rbrs)>>rbls;
                        return;
                    }
                }
                else  if ( Top.mb_num>=0)
                {
                    tbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))>0;
                    tbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))<0;

                    if (IS_INTER_MBTYPE(gmbs[Top.mb_num].mbtype) &&
                        (((RefIdxs[Top.mb_num].RefIdxs[Top.block_num-1]<<tbls)>>tbrs) == RefIndex))
                    {
                        *pMVx = MVs[Top.mb_num].MotionVectors[Top.block_num-1].mvx;
                        *pMVy = ((MVs[Top.mb_num].MotionVectors[Top.block_num-1].mvy+((MVs[Top.mb_num].MotionVectors[Top.block_num-1].mvy<0)&&tbls))<<tbrs)>>tbls;
                        return;
                    }
                }


                //LeftBlockNum=2;
                //LeftMB=GetLeftBlock(pMBInfo,LeftBlockNum);
                Left.mb_num=m_CurMBAddr;
                Left.block_num=1;
                TopLeft=m_cur_mb.CurrentBlockNeighbours.mb_above;
                TopLeft.block_num++;
                // init vars for median prediction
                isRightUnavailable = (TopRight.mb_num<0);
                if (isRightUnavailable)
                    isLeftUnavailable = (Top.mb_num<0);
            }
            //        diff = 2;
            break;
        case MBTYPE_INTER_8x8:
        case MBTYPE_INTER_8x8_REF0:
            {
                // Each 8x8 block of a macroblock can be subdivided into subblocks,
                // each having its own MV. The parameter 'block' has block and
                // subblock information:
                //  block 0..3, bits 2-3
                //  subblock 0..3, bits 0-1
                Ipp32s  left_edge_block = 0, top_edge_block = 0, right_edge_block = 0;

                switch (m_cur_mb.GlobalMacroblockInfo->sbtype[block>>2])
                {
                case SBTYPE_8x8:
                    Top.block_num=
                        Left.block_num=
                        TopLeft.block_num=
                        block2lin[block];
                    TopRight.block_num=
                        block2lin[block]+1;
                        GetLeftLocationForCurrentMBLumaMBAFF(&Left);
                        GetTopLocationForCurrentMBLumaMBAFF(&Top,0);
                        GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight);
                        GetTopLeftLocationForCurrentMBLumaMBAFF(&TopLeft);
                    switch (block>>2)
                    {
                    case 0:
                        left_edge_block = 1;
                        top_edge_block = 1;
                        isRightUnavailable = (Top.mb_num<0);
                        isLeftUnavailable = (TopLeft.mb_num<0);
                        break;
                    case 1:
                        left_edge_block = 0;
                        top_edge_block = 1;
                        isRightUnavailable = (TopRight.mb_num<0);
                        isLeftUnavailable = (Top.mb_num<0);
                        break;
                    case 2:
                        left_edge_block = 1;
                        top_edge_block = 0;
                        isRightUnavailable = 0;
                        break;
                    case 3:
                        left_edge_block = 0;
                        top_edge_block = 0;
                        isRightUnavailable = 1;
                        isLeftUnavailable = 0;
                        break;
                    }   // block
                    right_edge_block = left_edge_block == 0 ? 1 : 0;
                    break;
                case SBTYPE_8x4:
                    Top.block_num=
                        Left.block_num=
                        TopLeft.block_num=

⌨️ 快捷键说明

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