📄 umc_h263_video_encoder.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) 2005-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "vm_debug.h"
#include "vm_time.h"
#include "umc_h263_video_encoder.h"
#include "umc_video_data.h"
namespace UMC
{
H263VideoEncoder::H263VideoEncoder()
{
m_IsInit = false;
}
H263VideoEncoder::~H263VideoEncoder()
{
Close();
}
Status H263VideoEncoder::AllocateBuffers()
{
Status status = UMC_OK;
int i;
// allocate only frame memory, may be extended for whole buffers
for (i = 0; i < h263enc.mPlanes; i ++)
h263enc.mFrame[i].mid = 0;
for (i = 0; i < h263enc.mPlanes; i ++) {
status = m_pMemoryAllocator->Alloc(&h263enc.mFrame[i].mid, h263enc.mLumaPlaneSize + h263enc.mChromaPlaneSize + h263enc.mChromaPlaneSize, UMC_ALLOC_PERSISTENT);
if (status != UMC_OK)
return status;
}
return status;
}
Status H263VideoEncoder::FreeBuffers()
{
Status status = UMC_OK;
int i;
for (i = 0; i < h263enc.mPlanes; i ++) {
if (h263enc.mFrame[i].mid)
status = m_pMemoryAllocator->Free(h263enc.mFrame[i].mid);
if (status != UMC_OK)
return status;
}
return status;
}
void H263VideoEncoder::LockBuffers()
{
int i;
for (i = 0; i < h263enc.mPlanes; i ++) {
h263enc.mFrame[i].ap = (Ipp8u*)m_pMemoryAllocator->Lock(h263enc.mFrame[i].mid);
h263enc.mFrame[i].pY = h263enc.mFrame[i].ap + h263enc.mExpandSizeA + h263enc.mExpandSizeA * h263enc.mStepLuma;
h263enc.mFrame[i].pU = h263enc.mFrame[i].ap + h263enc.mLumaPlaneSize + (h263enc.mExpandSizeA >> 1) + (h263enc.mExpandSizeA >> 1) * h263enc.mStepChroma;
h263enc.mFrame[i].pV = h263enc.mFrame[i].ap + h263enc.mLumaPlaneSize + h263enc.mChromaPlaneSize + (h263enc.mExpandSizeA >> 1) + (h263enc.mExpandSizeA >> 1) * h263enc.mStepChroma;
}
}
Status H263VideoEncoder::UnlockBuffers()
{
Status status = UMC_OK;
int i;
for (i = 0; i < h263enc.mPlanes; i ++) {
status = m_pMemoryAllocator->Unlock(h263enc.mFrame[i].mid);
if (status != UMC_OK)
return status;
}
return status;
}
Status H263VideoEncoder::Reset()
{
return UMC_ERR_NOT_IMPLEMENTED;
}
Status H263VideoEncoder::SetParams(BaseCodecParams* params)
{
return UMC_ERR_NOT_IMPLEMENTED;
}
H263EncoderParams::H263EncoderParams()
{
// default values - required when run w/out par file
m_Param.advIntra = m_Param.advPred = m_Param.deblockFilt = 0;
m_Param.modQuant = 0;
m_Param.UMV = 0;
m_Param.calcPSNR = 0;
m_Param.MEaccuracy = 2;
m_Param.MEalgorithm = 1;
m_Param.IPicdist = 10;
m_Param.PPicdist = 1;
m_Param.PPicsearchHeight = 15;
m_Param.PPicsearchWidth = 15;
m_Param.RateControl = 0;
m_Param.SceneChangeThreshold = 50;
m_Param.BitRate = 400000;
m_Param.FrameSkip = 1;
m_Param.quantPPic = m_Param.quantIPic = 7;
// m_Param.quantBPic = 9;
m_Param.TimeIncrement = 1001;
m_Param.TimeResolution = 30000;
m_Param.bsBuffer = (Ipp8u*)1;
m_Param.bsBuffSize = 1; // encoder will not allocate buffer
m_Param.GOBheaders = 0;
// just in case
m_Param.Height = 288;
m_Param.Width = 352;
}
Status H263VideoEncoder::Init(BaseCodecParams* init)
{
VideoEncoderParams *VideoParams = DynamicCast<VideoEncoderParams>(init);
H263EncoderParams *pParam = DynamicCast<H263EncoderParams>(init);
h263e_Param *h263Params;
if (pParam) {
m_Param = *pParam;
}
if (VideoParams) {
h263Params = &m_Param.m_Param;
h263Params->Width = VideoParams->info.clip_info.width;
h263Params->Height = VideoParams->info.clip_info.height;
if (VideoParams->info.bitrate > 0) {
h263Params->RateControl = 1;
h263Params->BitRate = VideoParams->info.bitrate;
} else
h263Params->BitRate = 0;
{
Ipp64f finc;
Ipp32s fr_delta = (Ipp32s)(VideoParams->info.framerate * h263Params->TimeIncrement) - h263Params->TimeResolution;
Ipp32s tinc, tres, div0, div1, rem0, rem1, q;
fr_delta = h263e_Abs(fr_delta);
if (fr_delta > 500) {
tres = 1800000;
finc = (Ipp64f)tres / VideoParams->info.framerate;
tinc = (Ipp32s)finc;
div1 = (Ipp32s)(finc * (1.0 / 1001) + 0.5);
div0 = (Ipp32s)(finc * 0.001 + 0.5);
rem0 = div0 * 1000 - tinc;
rem1 = div1 * 1001 - tinc;
if (h263e_Abs(rem0) < h263e_Abs(rem1))
tinc = div0 * 1000;
else {
q = div1 / 60;
if (q * 60 == div1 && q <= 255) {
div1 = q;
tres = 30000;
}
tinc = div1 * 1001;
}
h263Params->TimeResolution = tres;
h263Params->TimeIncrement = tinc;
}
}
// while ((Ipp32s)((Ipp64f)h263Params->TimeResolution / VideoParams->info.framerate) > h263Params->TimeIncrement + 1001/2) {
// h263Params->TimeIncrement += 1001;
// }
//h263Params->NumOfFrames = VideoParams->numFramesToEncode;
m_Param.info.clip_info.width = h263Params->Width;
m_Param.info.clip_info.height = h263Params->Height;
m_Param.info.bitrate = h263Params->BitRate;
m_Param.info.framerate = (Ipp64f)h263Params->TimeResolution / h263Params->TimeIncrement;
// h263Params->numThreads = VideoParams->numThreads;
} else
return UMC_ERR_NULL_PTR;
if (m_IsInit)
Close();
Ipp32s h263status = h263enc.Init(h263Params);
if (h263status == H263_STS_ERR_PARAM)
return UMC_ERR_INVALID_PARAMS;
if (h263status == H263_STS_ERR_NOMEM)
return UMC_ERR_ALLOC;
m_FrameCount = 0;
if (VideoParams->info.color_format != YUV420) {
vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("Invalid color format: only YUV420 supported\n"));
return UMC_ERR_INVALID_PARAMS;
}
// create default memory allocator if not exist
Status status = BaseCodec::Init(init);
if (status != UMC_OK)
return status;
status = AllocateBuffers();
if (status != UMC_OK)
return status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -