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

📄 mp4decvop.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 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) 2001-2008 Intel Corporation. All Rights Reserved.
//
//  Description:    Decodes MPEG-4 bitstream.
//
*/

#include "umc_defs.h"

#if defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)

#include "mp4.h"
#include "mp4dec.h"

#pragma warning(disable : 188)  // enumerated type mixed with another type ICL

void mp4_ResetVOL(mp4_Info *pInfo)
{
    pInfo->VisualObject.VideoObject.VOPindex = 0;
    pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;

    pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code = 0;
    pInfo->VisualObject.vFrame = NULL;
}

static mp4_Status mp4_AllocInitFrame(mp4_Frame* pFrame, Ipp32s mbPerRow, Ipp32s mbPerCol)
{
    Ipp32s w, h;

    w = (mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
    h = (mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
    pFrame->stepY = w;
    pFrame->apY = ippsMalloc_8u(w * h);
    if (!pFrame->apY)
        return MP4_STATUS_NO_MEM;
    ippsSet_8u(0, pFrame->apY, w * h);
    pFrame->pY = pFrame->apY + w * 16 + 16;
    w >>= 1;
    h >>= 1;
    pFrame->stepCb = w;
    pFrame->apCb = ippsMalloc_8u(w * h);
    if (!pFrame->apCb)
        return MP4_STATUS_NO_MEM;
    ippsSet_8u(128, pFrame->apCb, w * h);
    pFrame->pCb = pFrame->apCb + w * 8 + 8;
    pFrame->stepCr = w;
    pFrame->apCr = ippsMalloc_8u(w * h);
    if (!pFrame->apCr)
        return MP4_STATUS_NO_MEM;
    pFrame->pCr = pFrame->apCr + w * 8 + 8;
    ippsSet_8u(128, pFrame->apCr, w * h);
    return MP4_STATUS_OK;
}

/*
//  mp4_Info for decoding of Video Object Layer
*/
mp4_Status mp4_InitVOL(mp4_Info* pInfo)
{
    Ipp32s mbPerRow, mbPerCol, specSize;

    if (pInfo->VisualObject.VideoObject.short_video_header) {
        pInfo->noBVOPs = 1;
    } else {
        if (pInfo->strictSyntaxCheck) {
            if (pInfo->VisualObject.VideoObject.random_accessible_vol)
                pInfo->noPVOPs = pInfo->noBVOPs = 1;
            if (pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_SIMPLE ||
                pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE ||
                pInfo->VisualObject.VideoObject.VOLControlParameters.low_delay) {
                pInfo->noBVOPs = 1;
            }
        }
    }
    if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
        mbPerRow = (pInfo->VisualObject.VideoObject.width + 15) >> 4;
        mbPerCol = (pInfo->VisualObject.VideoObject.height + 15) >> 4;
        // current frame
//        if (mp4_AllocInitFrame(&pInfo->VisualObject.cFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
//            return MP4_STATUS_NO_MEM;
        if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
            // ref in past frame
//            if (mp4_AllocInitFrame(&pInfo->VisualObject.rFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
//                return MP4_STATUS_NO_MEM;
            // ref in future frame
//            if (mp4_AllocInitFrame(&pInfo->VisualObject.nFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
//                return MP4_STATUS_NO_MEM;
            // motion info (not needed for Sprites)
            pInfo->VisualObject.VideoObject.MBinfo = (mp4_MacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_MacroBlock));
            if (!pInfo->VisualObject.VideoObject.MBinfo) return MP4_STATUS_NO_MEM;
#ifdef USE_NOTCODED_STATE
            // not_coded MB state
            pInfo->VisualObject.VideoObject.ncState = ippsMalloc_8u(mbPerCol * mbPerRow);
            if (!pInfo->VisualObject.VideoObject.ncState) return MP4_STATUS_NO_MEM;
            pInfo->VisualObject.VideoObject.ncStateCleared = 0;
#endif
        } else { // data for static sprite
            mbPerRow = pInfo->VisualObject.sFrame.mbPerRow = (pInfo->VisualObject.VideoObject.sprite_width + 15) >> 4;
            mbPerCol = pInfo->VisualObject.sFrame.mbPerCol = (pInfo->VisualObject.VideoObject.sprite_height + 15) >> 4;
//            if (mp4_AllocInitFrame(&pInfo->VisualObject.sFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
//                return MP4_STATUS_NO_MEM;
        }
        pInfo->VisualObject.VideoObject.MacroBlockPerRow = mbPerRow;
        pInfo->VisualObject.VideoObject.MacroBlockPerCol = mbPerCol;
        pInfo->VisualObject.VideoObject.MacroBlockPerVOP = mbPerRow * mbPerCol;
        pInfo->VisualObject.VideoObject.mbns = mp4_GetMacroBlockNumberSize(pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
#ifdef _OMP_KARABAS
        if (pInfo->num_threads < 1 || pInfo->num_threads > mp4_GetNumOfThreads())
            pInfo->num_threads = mp4_GetNumOfThreads();
        pInfo->pMBinfoMT = (mp4_MacroBlockMT*)ippsMalloc_8u(mbPerRow * pInfo->num_threads * sizeof(mp4_MacroBlockMT));
        if(!pInfo->pMBinfoMT) return MP4_STATUS_NO_MEM;
#endif // _OMP_KARABAS
        if (!pInfo->VisualObject.VideoObject.short_video_header) {
            // Intra Prediction info (not needed for SVH)
            pInfo->VisualObject.VideoObject.IntraPredBuff.quant = ippsMalloc_8u(mbPerRow + 1);
            if (!pInfo->VisualObject.VideoObject.IntraPredBuff.quant) return MP4_STATUS_NO_MEM;
            pInfo->VisualObject.VideoObject.IntraPredBuff.block = (mp4_IntraPredBlock*)ippsMalloc_8u((mbPerRow + 1)*6*sizeof(mp4_IntraPredBlock));
            if (!pInfo->VisualObject.VideoObject.IntraPredBuff.block) return MP4_STATUS_NO_MEM;
            {
                mp4_IntraPredBlock *mbCurr = pInfo->VisualObject.VideoObject.IntraPredBuff.block;
                mp4_IntraPredBlock *mbA = mbCurr, *mbB = pInfo->VisualObject.VideoObject.IntraPredBuff.dcB, *mbC = mbCurr + 6;
                Ipp32s              j;

                for (j = 0; j < mbPerRow; j ++) {
                    mbCurr[0].predA = &mbA[1];  mbCurr[0].predB = &mbB[3];  mbCurr[0].predC = &mbC[2];
                    mbCurr[1].predA = &mbC[0];  mbCurr[1].predB = &mbC[2];  mbCurr[1].predC = &mbC[3];
                    mbCurr[2].predA = &mbA[3];  mbCurr[2].predB = &mbA[1];  mbCurr[2].predC = &mbC[0];
                    mbCurr[3].predA = &mbC[2];  mbCurr[3].predB = &mbC[0];  mbCurr[3].predC = &mbC[1];
                    mbCurr[4].predA = &mbA[4];  mbCurr[4].predB = &mbB[4];  mbCurr[4].predC = &mbC[4];
                    mbCurr[5].predA = &mbA[5];  mbCurr[5].predB = &mbB[5];  mbCurr[5].predC = &mbC[5];
                    mbCurr += 6;  mbA += 6;  mbC += 6;
                }
            }
            if (pInfo->VisualObject.VideoObject.data_partitioned) {
                // DataPart info
                pInfo->VisualObject.VideoObject.DataPartBuff = (mp4_DataPartMacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_DataPartMacroBlock));
                if (!pInfo->VisualObject.VideoObject.DataPartBuff) return MP4_STATUS_NO_MEM;
            }
            if (pInfo->VisualObject.VideoObject.interlaced) {
                // Field MV for B-VOP
                pInfo->VisualObject.VideoObject.FieldMV = (IppMotionVector*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(IppMotionVector)*2);
                if (!pInfo->VisualObject.VideoObject.FieldMV) return MP4_STATUS_NO_MEM;
            }
            ippiQuantInvIntraGetSize_MPEG4(&specSize);
            pInfo->VisualObject.VideoObject.QuantInvIntraSpec = (IppiQuantInvIntraSpec_MPEG4*)ippsMalloc_8u(specSize);
            ippiQuantInvIntraInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.intra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, 8);
            ippiQuantInvInterGetSize_MPEG4(&specSize);
            pInfo->VisualObject.VideoObject.QuantInvInterSpec = (IppiQuantInvInterSpec_MPEG4*)ippsMalloc_8u(specSize);
            ippiQuantInvInterInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.nonintra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvInterSpec, 8);
            ippiWarpGetSize_MPEG4(&specSize);
            pInfo->VisualObject.VideoObject.WarpSpec = (IppiWarpSpec_MPEG4*)ippsMalloc_8u(specSize);
        }
    }
    return MP4_STATUS_OK;
}

/*
//  Free memory allocated for mp4_Info
*/
mp4_Status mp4_FreeVOL(mp4_Info* pInfo)
{
    if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
//        ippsFree(pInfo->VisualObject.cFrame.apY);  pInfo->VisualObject.cFrame.apY  = pInfo->VisualObject.cFrame.pY  = NULL;
//        ippsFree(pInfo->VisualObject.cFrame.apCb); pInfo->VisualObject.cFrame.apCb = pInfo->VisualObject.cFrame.pCb = NULL;
//        ippsFree(pInfo->VisualObject.cFrame.apCr); pInfo->VisualObject.cFrame.apCr = pInfo->VisualObject.cFrame.pCr = NULL;
        if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
//            if (!pInfo->noPVOPs) {
//            ippsFree(pInfo->VisualObject.rFrame.apY);  pInfo->VisualObject.rFrame.apY  = pInfo->VisualObject.rFrame.pY  = NULL;
//            ippsFree(pInfo->VisualObject.rFrame.apCb); pInfo->VisualObject.rFrame.apCb = pInfo->VisualObject.rFrame.pCb = NULL;
//            ippsFree(pInfo->VisualObject.rFrame.apCr); pInfo->VisualObject.rFrame.apCr = pInfo->VisualObject.rFrame.pCr = NULL;
//            }
//            if (!pInfo->noBVOPs) {
//            ippsFree(pInfo->VisualObject.nFrame.apY);  pInfo->VisualObject.nFrame.apY  = pInfo->VisualObject.nFrame.pY  = NULL;
//            ippsFree(pInfo->VisualObject.nFrame.apCb); pInfo->VisualObject.nFrame.apCb = pInfo->VisualObject.nFrame.pCb = NULL;
//            ippsFree(pInfo->VisualObject.nFrame.apCr); pInfo->VisualObject.nFrame.apCr = pInfo->VisualObject.nFrame.pCr = NULL;
//            }
            ippsFree(pInfo->VisualObject.VideoObject.MBinfo); pInfo->VisualObject.VideoObject.MBinfo = NULL;
#ifdef USE_NOTCODED_STATE
            ippsFree(pInfo->VisualObject.VideoObject.ncState);
#endif
        } else {
//            ippsFree(pInfo->VisualObject.sFrame.apY);  pInfo->VisualObject.sFrame.apY  = pInfo->VisualObject.sFrame.pY  = NULL;
//            ippsFree(pInfo->VisualObject.sFrame.apCb); pInfo->VisualObject.sFrame.apCb = pInfo->VisualObject.sFrame.pCb = NULL;
//            ippsFree(pInfo->VisualObject.sFrame.apCr); pInfo->VisualObject.sFrame.apCr = pInfo->VisualObject.sFrame.pCr = NULL;
        }
        if (!pInfo->VisualObject.VideoObject.short_video_header) {
            ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.quant); pInfo->VisualObject.VideoObject.IntraPredBuff.quant = NULL;
            ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.block); pInfo->VisualObject.VideoObject.IntraPredBuff.block = NULL;
            if (pInfo->VisualObject.VideoObject.data_partitioned) {
                ippsFree(pInfo->VisualObject.VideoObject.DataPartBuff); pInfo->VisualObject.VideoObject.DataPartBuff = NULL;
            }
            if (pInfo->VisualObject.VideoObject.interlaced) {
                ippsFree(pInfo->VisualObject.VideoObject.FieldMV); pInfo->VisualObject.VideoObject.FieldMV = NULL;
            }
            ippsFree(pInfo->VisualObject.VideoObject.QuantInvIntraSpec); pInfo->VisualObject.VideoObject.QuantInvIntraSpec = NULL;
            ippsFree(pInfo->VisualObject.VideoObject.QuantInvInterSpec); pInfo->VisualObject.VideoObject.QuantInvInterSpec = NULL;
            ippsFree(pInfo->VisualObject.VideoObject.WarpSpec); pInfo->VisualObject.VideoObject.WarpSpec = NULL;
        }
#ifdef _OMP_KARABAS
        ippsFree(pInfo->pMBinfoMT); pInfo->pMBinfoMT = NULL;
#endif // _OMP_KARABAS
    } /* //f else {
        // free current
        mp4_FreeVOPShape(pInfo);
        mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
        // free ref
        mp4_FreeVOPShape(pInfo);
        mp4_SWAP(mp4_Frame, pInfo->VisualObject.nFrame, pInfo->VisualObject.cFrame);
        // free future
        mp4_FreeVOPShape(pInfo);
        if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC) {
            // free sprite
            mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
            mp4_FreeVOPShape(pInfo);
        }
    } */
    return MP4_STATUS_OK;
}


mp4_Status mp4_DecodeMVD(mp4_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy, Ipp32s fcode)
{
    const mp4_VLC1 *pTab;
    Ipp32s          mvd, sign;
    Ipp32u          code;
    Ipp32s          factor = fcode - 1;

    /* decode MVDx */
    code = mp4_ShowBits(pInfo, 12);
    if (code >= 128)
        pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
    else if (code >= 2)
        pTab = mp4_MVD_B12_1 + (code - 2);
    else {
        mp4_Error("Error: decoding MVD");
        return MP4_STATUS_ERROR;
    }
    mvd = pTab->code;
    mp4_FlushBits(pInfo, pTab->len);
    if (mvd) {
        sign = mp4_GetBit(pInfo);
        if (factor) {
            code = mp4_GetBits9(pInfo, factor);
            mvd = ((mvd - 1) << factor) + code + 1;
        }
        if (sign)
            mvd = -mvd;
    }
    *mvdx = mvd;
    /* decode MVDy */
    code = mp4_ShowBits(pInfo, 12);
    if (code >= 128)
        pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
    else if (code >= 2)
        pTab = mp4_MVD_B12_1 + (code - 2);
    else {
        mp4_Error("Error: decoding MVD");
        return MP4_STATUS_ERROR;
    }
    mvd = pTab->code;
    mp4_FlushBits(pInfo, pTab->len);
    if (mvd) {
        sign = mp4_GetBit(pInfo);
        if (factor) {
            code = mp4_GetBits9(pInfo, factor);
            mvd = ((mvd - 1) << factor) + code + 1;
        }
        if (sign)
            mvd = -mvd;

⌨️ 快捷键说明

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