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

📄 umc_mpeg4_video_decoder.cpp

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

#include "umc_defs.h"

#if defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)

#include <string.h>
#include "vm_debug.h"
#include "umc_mpeg4_video_decoder.h"
#include "umc_video_data.h"

namespace UMC
{

VideoDecoder *CreateMPEG4Decoder() { return (new MPEG4VideoDecoder()); }

Status MPEG4VideoDecoder::AllocateInitFrame(mp4_Frame* pFrame)
{
    Status  status;
    Ipp32s  w, h;
    Ipp8u  *p;

    w = (pFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
    h = (pFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
    status = m_pMemoryAllocator->Alloc(&pFrame->mid, w * h + (w * h >> 1), UMC_ALLOC_PERSISTENT);
    if (status != UMC_OK)
        return status;
    p = (Ipp8u*)m_pMemoryAllocator->Lock(pFrame->mid);
    ippsSet_8u(0, p, w * h);
    ippsSet_8u(128, p + w * h, w * h >> 1);
    status = m_pMemoryAllocator->Unlock(pFrame->mid);
    if (status != UMC_OK)
        return status;
    pFrame->stepY = w;
    pFrame->stepCb = w >> 1;
    pFrame->stepCr = w >> 1;
    return UMC_OK;
}

void MPEG4VideoDecoder::LockFrame(mp4_Frame* pFrame)
{
    Ipp32u  w, h;

    w = (pFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
    h = (pFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
    pFrame->apY = (Ipp8u*)m_pMemoryAllocator->Lock(pFrame->mid);
    pFrame->pY = pFrame->apY + w * 16 + 16;
    pFrame->apCb = pFrame->apY + w * h;
    w >>= 1;
    h >>= 1;
    pFrame->pCb = pFrame->apCb + w * 8 + 8;
    pFrame->apCr = pFrame->apCb + w * h;
    pFrame->pCr = pFrame->apCr + w * 8 + 8;
}

Status MPEG4VideoDecoder::AllocateBuffers()
{
    Status  status = UMC_OK;

    // allocate only frame memory, may be extended for whole buffers
    if (m_decInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
        // current frame
        m_decInfo->VisualObject.cFrame.mbPerRow = (m_decInfo->VisualObject.VideoObject.width + 15) >> 4;
        m_decInfo->VisualObject.cFrame.mbPerCol = (m_decInfo->VisualObject.VideoObject.height + 15) >> 4;
        status = AllocateInitFrame(&m_decInfo->VisualObject.cFrame);
        if (status != UMC_OK)
            return status;
        if (m_decInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
            // ref in past frame
            if (!m_decInfo->noPVOPs) {
                m_decInfo->VisualObject.rFrame.mbPerRow = m_decInfo->VisualObject.cFrame.mbPerRow;
                m_decInfo->VisualObject.rFrame.mbPerCol = m_decInfo->VisualObject.cFrame.mbPerCol;
                status = AllocateInitFrame(&m_decInfo->VisualObject.rFrame);
                if (status != UMC_OK)
                    return status;
            }
            // ref in future frame
            if (!m_decInfo->noBVOPs) {
                m_decInfo->VisualObject.nFrame.mbPerRow = m_decInfo->VisualObject.cFrame.mbPerRow;
                m_decInfo->VisualObject.nFrame.mbPerCol = m_decInfo->VisualObject.cFrame.mbPerCol;
                status = AllocateInitFrame(&m_decInfo->VisualObject.nFrame);
                if (status != UMC_OK)
                    return status;
            }
        } else {
            // data for static sprite
            m_decInfo->VisualObject.sFrame.mbPerRow = (m_decInfo->VisualObject.VideoObject.sprite_width + 15) >> 4;
            m_decInfo->VisualObject.sFrame.mbPerCol = (m_decInfo->VisualObject.VideoObject.sprite_height + 15) >> 4;
            status = AllocateInitFrame(&m_decInfo->VisualObject.sFrame);
            if (status != UMC_OK)
                return status;
        }
    }
    if (mp4_InitVOL(m_decInfo) != MP4_STATUS_OK) {
        mp4_Error("Error: No memory to allocate internal buffers\n");
        return UMC_ERR_ALLOC;
    }
    return status;
}

Status MPEG4VideoDecoder::FreeBuffers()
{
    Status  status = UMC_OK;

    if (m_decInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
        if (m_decInfo->VisualObject.cFrame.mid) {
            status = m_pMemoryAllocator->Free(m_decInfo->VisualObject.cFrame.mid);
            m_decInfo->VisualObject.cFrame.mid = 0;
            if (status != UMC_OK)
                return status;
        }
        if (m_decInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
            if (m_decInfo->VisualObject.rFrame.mid) {
                if (!m_decInfo->noPVOPs)
                    status = m_pMemoryAllocator->Free(m_decInfo->VisualObject.rFrame.mid);
                m_decInfo->VisualObject.rFrame.mid = 0;
                if (status != UMC_OK)
                    return status;
            }
            if (m_decInfo->VisualObject.nFrame.mid) {
                if (!m_decInfo->noBVOPs)
                    status = m_pMemoryAllocator->Free(m_decInfo->VisualObject.nFrame.mid);
                m_decInfo->VisualObject.nFrame.mid = 0;
                if (status != UMC_OK)
                    return status;
            }
        } else {
            if (m_decInfo->VisualObject.sFrame.mid) {
                status = m_pMemoryAllocator->Free(m_decInfo->VisualObject.sFrame.mid);
                m_decInfo->VisualObject.sFrame.mid = 0;
                if (status != UMC_OK)
                    return status;
            }
        }
    }
    mp4_FreeVOL(m_decInfo);
    return status;
}

void MPEG4VideoDecoder::LockBuffers()
{
    if (m_decInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
        LockFrame(&m_decInfo->VisualObject.cFrame);
        if (m_decInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
            LockFrame(&m_decInfo->VisualObject.rFrame);
            LockFrame(&m_decInfo->VisualObject.nFrame);
        } else {
            LockFrame(&m_decInfo->VisualObject.sFrame);
        }
    }
}

Status MPEG4VideoDecoder::UnlockBuffers()
{
    Status status = UMC_OK;

    if (m_decInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
        status = m_pMemoryAllocator->Unlock(m_decInfo->VisualObject.cFrame.mid);
        if (status != UMC_OK)
            return status;
        if (m_decInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
            status = m_pMemoryAllocator->Unlock(m_decInfo->VisualObject.rFrame.mid);
            if (status != UMC_OK)
                return status;
            status = m_pMemoryAllocator->Unlock(m_decInfo->VisualObject.nFrame.mid);
            if (status != UMC_OK)
                return status;
        } else {
            status = m_pMemoryAllocator->Unlock(m_decInfo->VisualObject.sFrame.mid);
            if (status != UMC_OK)
                return status;
        }
    }
    return status;
}

Status MPEG4VideoDecoder::Init(BaseCodecParams *lpInit)
{
    Status  status = UMC_OK;
    VideoDecoderParams *pParam = DynamicCast<VideoDecoderParams> (lpInit);

    Close();
    if (NULL == m_decInfo)
        return UMC_ERR_ALLOC;
    if (NULL == pParam)
        return UMC_ERR_NULL_PTR;
    // create default memory allocator if not exist
    status = BaseCodec::Init(lpInit);
    if (status != UMC_OK)
        return status;
    m_time_reset = 0;
    m_dec_time_fr = 0.0;
    m_dec_time_base = -1.0;
    m_dec_time_prev = 0.0;
    m_dec_time_frinc = (pParam->info.framerate > 0) ? 1.0 / pParam->info.framerate : 0.0;
    m_is_skipped_b = m_skipped_fr = m_b_prev = 0;
    m_Param = *pParam;
    m_IsInit = m_IsInitBase = false;
    memset(m_decInfo, 0, sizeof(mp4_Info));
    m_decInfo->stopOnErr = 0;
    m_decInfo->strictSyntaxCheck = 0;
    m_decInfo->VisualObject.verid = 1;
    m_DeringingProcPlane[0] = m_DeringingProcPlane[1] = m_DeringingProcPlane[2] = false;
    m_DeblockingProcPlane[0] = m_DeblockingProcPlane[1] = m_DeblockingProcPlane[2] = false;
    m_DeblockingTHR1 = 2;
    m_DeblockingTHR2 = 6;

    ppFrame0.mid = ppFrame1.mid = 0;
    if (NULL != pParam->m_pData) {
        if (pParam->m_pData->GetTime() >= 0.0)
            m_dec_time_base = pParam->m_pData->GetTime();
        m_decInfo->buflen = pParam->m_pData->GetDataSize();
        if (m_decInfo->buflen > 0) {
            m_decInfo->bufptr = m_decInfo->buffer = reinterpret_cast<Ipp8u *> (pParam->m_pData->GetDataPointer());
            m_decInfo->bitoff = 0;
            status = InsideInit();
            pParam->m_pData->MoveDataPointer(static_cast<Ipp32u>((size_t)m_decInfo->bufptr - (size_t)m_decInfo->buffer));
        }
    }
    if (UMC_OK == status) {
        m_PostProcessing = pParam->pPostProcessing;
        // set VOP size if it is unknown in splitter
        if (pParam->info.clip_info.width == 0 || pParam->info.clip_info.height == 0) {
            if (m_decInfo->VisualObject.VideoObject.width == 0 && m_decInfo->VisualObject.VideoObject.height== 0)
                return UMC_ERR_INIT;
            else {
                pParam->info.clip_info.width = m_Param.info.clip_info.width = m_decInfo->VisualObject.VideoObject.width;
                pParam->info.clip_info.height = m_Param.info.clip_info.height = m_decInfo->VisualObject.VideoObject.height;
            }
        }
        m_ClipInfo = m_Param.info;
        m_IsInitBase = true;
    }
    return status;
}

Status MPEG4VideoDecoder::InsideInit()
{
    Status  status;
    Ipp32u  code, h_vo_found = 0, h_vos_found = 0;

    m_buffered_frame = m_Param.lFlags & FLAG_VDEC_REORDER;
    if (m_Param.info.stream_subtype == MPEG4_VIDEO_DIVX5) {
        m_decInfo->ftype = 2;
        m_decInfo->ftype_f = 1;
    } else if (m_Param.info.stream_subtype == MPEG4_VIDEO_QTIME) {
        m_decInfo->ftype = 1;
        m_decInfo->ftype_f = 0;
    } else { // UNDEF_VIDEO_SUBTYPE
        m_decInfo->ftype = 0;
        m_decInfo->ftype_f = 0;
    }
    m_decInfo->num_threads = m_Param.numThreads;
    for (;;) {
        if (m_decInfo->strictSyntaxCheck) {
            if (!mp4_SeekStartCodeOrShortPtr(m_decInfo)) {
                mp4_Error("Error: Can't find Visual Object Sequence or start code or short_video_start_marker");
                return MP4_STATUS_PARSE_ERROR;
            }
            // check short_video_start_marker
            if (mp4_IsShortCode(m_decInfo)) {
                if ((status = mp4_Parse_VideoObject(m_decInfo)) != MP4_STATUS_OK)
                    return status;
            } else {
                if (mp4_IsStartCodeValue(m_decInfo, MP4_VISUAL_OBJECT_SEQUENCE_SC, MP4_VISUAL_OBJECT_SEQUENCE_SC)) {
                    m_decInfo->bufptr ++;
                    if ((status = mp4_Parse_VisualObjectSequence(m_decInfo)) != MP4_STATUS_OK)
                        return status;
                } else {
                    mp4_Error("Error: Can't find Visual Object Sequence start code");
                    return MP4_STATUS_PARSE_ERROR;
                }
                if (!mp4_SeekStartCodePtr(m_decInfo)) {
                    mp4_Error("Error: Can't find Visual Object start code");
                    return MP4_STATUS_PARSE_ERROR;
                }
                if (mp4_IsStartCodeValue(m_decInfo, MP4_VISUAL_OBJECT_SC, MP4_VISUAL_OBJECT_SC)) {
                    m_decInfo->bufptr ++;
                    if ((status = mp4_Parse_VisualObject(m_decInfo)) != MP4_STATUS_OK)
                        return status;
                } else {
                    mp4_Error("Error: Can't find Visual Object start code");
                    return MP4_STATUS_PARSE_ERROR;
                }
                if (!mp4_SeekStartCodePtr(m_decInfo)) {
                    mp4_Error("Error: Can't find Video Object start code");
                    return MP4_STATUS_PARSE_ERROR;
                }
                if (mp4_IsStartCodeValue(m_decInfo, MP4_VIDEO_OBJECT_MIN_SC,  MP4_VIDEO_OBJECT_MAX_SC)) {
                    m_decInfo->bufptr ++;
                    if ((status = mp4_Parse_VideoObject(m_decInfo)) != MP4_STATUS_OK)
                        return status;
                } else {
                    mp4_Error("Error: Can't find Video Object start code");
                    return MP4_STATUS_PARSE_ERROR;
                }
            }
        } else {
            if (!mp4_SeekStartCodeOrShortPtr(m_decInfo)) {
                mp4_Error("Error: Can't find Visual Object or Video Object start codes or short_video_start_marker\n");
                return UMC_ERR_SYNC;
            }
            // check short_video_start_marker
            if (mp4_IsShortCode(m_decInfo)) {
                code = MP4_VIDEO_OBJECT_MIN_SC;
            } else {
                code = mp4_GetBits(m_decInfo, 8);
                if (!h_vos_found && code == MP4_VISUAL_OBJECT_SEQUENCE_SC) {
                    h_vos_found = 1;

⌨️ 快捷键说明

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