📄 umc_vc1_enc_sm.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) 2007 Intel Corporation. All Rights Reserved.
//
//
// VC-1 (VC1) encoder, vc1 encoder simple profile
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_VC1_VIDEO_ENCODER)
#include "umc_vc1_enc_sm.h"
#include "umc_structures.h"
#include "umc_video_data.h"
#include "ippi.h"
#include "umc_vc1_enc_debug.h"
namespace UMC_VC1_ENCODER
{
UMC::Status VC1EncoderSM::Init(UMC::VC1EncoderParams* pParams)
{
UMC::Status err = UMC::UMC_OK;
Ipp32u w=0, h=0;
if(!m_pMemoryAllocator)
return UMC::UMC_ERR_INIT;
Close();
m_uiGOPLength = (pParams->m_uiGOPLength!=0)?
pParams->m_uiGOPLength:1;
m_uiBFrmLength = (pParams->m_uiBFrmLength < m_uiGOPLength)?
pParams->m_uiBFrmLength:m_uiGOPLength-1;
m_bSequenceHeader = false;
m_iFrameCount = 0;
m_uiPictuteQuantIndex = 7;
m_bHalfQuant = false;
m_bFrameRecoding = pParams->m_bFrameRecoding;
//---------Sequence--------------------------------------------
m_SH = new VC1EncoderSequenceSM;
if (!m_SH)
return UMC::UMC_ERR_ALLOC;
err = m_SH->Init(pParams);
if (err != UMC::UMC_OK)
return err;
err = m_SH->CheckParameters(m_cLastError);
if (err != UMC::UMC_OK)
return err;
w = m_SH->GetNumMBInRow();
h = m_SH->GetNumMBInCol();
//------------Planes for decoding -------------------------------
m_pStoredFrames = new StoredFrames;
if (!m_pStoredFrames)
return UMC::UMC_ERR_ALLOC;
m_pGOP = new GOP;
if (!m_pGOP)
return UMC::UMC_ERR_ALLOC;
m_pWaitingList = new WaitingList;
if (!m_pWaitingList)
return UMC::UMC_ERR_ALLOC;
m_pStoredFrames->SetMemoryAllocator(m_pMemoryAllocator, m_bOwnAllocator);
err = m_pStoredFrames->Init(m_uiBFrmLength, pParams->info.clip_info.width,pParams->info.clip_info.height, 32);
if (err !=UMC::UMC_OK)
return err;
err =m_pGOP->Init(m_uiBFrmLength);
if (err !=UMC::UMC_OK)
return err;
err =m_pWaitingList->Init(m_uiBFrmLength);
if (err !=UMC::UMC_OK)
return err;
if (m_uiBFrmLength)
{
/* we should save MV for direct prediction in B frames*/
if(m_pMemoryAllocator->Alloc(&m_SavedMVID, w*h*2*sizeof(Ipp16s),
UMC::UMC_ALLOC_PERSISTENT, 16) != UMC::UMC_OK )
return UMC::UMC_ERR_ALLOC;
m_pSavedMV = (Ipp16s*)m_pMemoryAllocator->Lock(m_SavedMVID);
}
//---------------MBs-----------------------------------------------
m_pMBs = new VC1EncoderMBs;
if (!m_pMBs)
return UMC::UMC_ERR_ALLOC;
m_pMBs->SetMemoryAllocator(m_pMemoryAllocator, m_bOwnAllocator);
err = m_pMBs->Init(w,2);
if (err != UMC::UMC_OK)
return err;
m_pCodedMB = new VC1EncoderCodedMB [w*h];
if (!m_pCodedMB)
return UMC::UMC_ERR_ALLOC;
m_pCurrPicture = new VC1EncoderPictureSM;
if (!m_pCurrPicture)
return UMC::UMC_ERR_ALLOC;
//---------------Motion estimation
if(pParams->m_uiGOPLength > 1)
{
m_pME = new UMC::MeBase;
if(!m_pME)
return err;
UMC::MeInitParams MEParamsInit;
memset(&MEParamsInit,0,sizeof(MEParamsInit));
MEParamsInit.width = pParams->info.clip_info.width;
MEParamsInit.height = pParams->info.clip_info.height;
MEParamsInit.refPadding = 32;
MEParamsInit.MbPart = UMC::Mb16x16;
MEParamsInit.CostMetrics = UMC::SADT;
if(pParams->m_uiBFrmLength)
MEParamsInit.SearchDirection = UMC::bidir_search;
else
MEParamsInit.SearchDirection = UMC::forward_search;
err = m_pME->Init(&MEParamsInit);
if(!err)
return UMC::UMC_ERR_INIT;
m_MESearchSpeed = pParams->m_uiMESearchSpeed;
}
m_pCurrPicture->SetMEParams(m_pME, m_MESearchSpeed);
//--------------Bit rate-------------------------------------------
m_BitRateControl = new VC1BitRateControl();
if (!m_BitRateControl)
return UMC::UMC_ERR_ALLOC;
m_SH->SetLevel(m_BitRateControl->GetLevel(m_SH->GetProfile(),pParams->info.bitrate, w, h));
err = m_BitRateControl->Init((pParams->info.clip_info.height*pParams->info.clip_info.width*3)/2,
pParams->info.bitrate, pParams->info.framerate, VC1_BRC_HIGHT_QUALITY_MODE,
m_uiGOPLength, m_uiBFrmLength, pParams->m_iConstQuant);
if (err != UMC::UMC_OK)
return err;
/*if (buffer number < 0) InitBuffer function will set corresponding number and
initialize it as new buffer
if it is number of existing buffer, it will change buffer params
if buffer size <=0 or > maxsize, buffer size will be equal to buffer size*/
err = m_BitRateControl->InitBuffer(m_SH->GetProfile(),m_SH->GetLevel(),
pParams->m_uiHRDBufferSize, pParams->m_uiHRDBufferInitFullness);
if (err != UMC::UMC_OK)
return err;
//-----------Bit stream ----------------------------------------------------
m_CodedFrame = new VC1EncoderBitStreamSM;
if (!m_CodedFrame)
return UMC::UMC_ERR_ALLOC;
#ifdef VC1_ENC_STAT
m_pEncStat = new EncoderStatistic;
if (!m_pEncStat)
return UMC::UMC_ERR_ALLOC;
err = m_pEncStat->Init(w,h);
if (err != UMC::UMC_OK)
return err;
#endif
#ifdef VC1_ENC_DEBUG_ON
pDebug = new VC1EncDebug;
assert(pDebug != NULL);
pDebug->Init(w, h);
#endif
return UMC::UMC_OK;
}
UMC::Status VC1EncoderSM::Close()
{
if (m_SH)
{
delete m_SH;
m_SH = 0;
}
if (m_pCurrPicture)
{
delete m_pCurrPicture;
m_pCurrPicture = 0;
}
if(m_BitRateControl)
{
delete m_BitRateControl;
m_BitRateControl = NULL;
}
if (m_pWaitingList)
{
delete m_pWaitingList;
m_pWaitingList = 0;
}
if (m_pGOP)
{
delete m_pGOP;
m_pGOP = 0;
}
if (m_pStoredFrames)
{
delete m_pStoredFrames;
m_pStoredFrames = 0;
}
if(m_pMemoryAllocator)
{
m_pMemoryAllocator->Unlock(m_SavedMVID);
if(m_bOwnAllocator == true)
{
m_pMemoryAllocator->Free(m_SavedMVID);
}
}
m_SavedMVID = (UMC::MemID)-1;
m_pSavedMV = 0;
if(m_pCodedMB)
{
delete [] m_pCodedMB;
m_pCodedMB = 0;
}
#ifdef VC1_ENC_STAT
if (m_pEncStat)
{
delete m_pEncStat;
m_pEncStat = 0;
}
#endif
if(m_pME)
{
delete m_pME;
m_pME = NULL;
}
#ifdef VC1_ENC_DEBUG_ON
if(pDebug)
{
delete pDebug;
pDebug = NULL;
}
#endif
return UMC::UMC_OK;
}
Ipp8u VC1EncoderSM::GetRoundControl(ePType pictureType, Ipp8u roundControl)
{
switch (pictureType)
{
case VC1_ENC_I_FRAME:
case VC1_ENC_BI_FRAME:
roundControl = 1;
break;
case VC1_ENC_P_FRAME:
roundControl = !roundControl;
break;
default:
roundControl = roundControl;
break;
}
return roundControl;
}
UMC::Status VC1EncoderSM::GetFrame(UMC::MediaData *in, UMC::MediaData *out)
{
UMC::Status err = UMC::UMC_ERR_NOT_ENOUGH_DATA;
UMC::VideoData* pVideoData = (in)? DynamicCast<UMC::VideoData> (in):0;
double time = 0;
size_t seqHeaderLen = 0;
Frame* frame = 0;
bool stored = false;
bool frame_recoding = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -