📄 umc_mpeg4_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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG4_VIDEO_ENCODER)
#include "umc_mpeg4_video_encoder.h"
#include "umc_video_data.h"
#include "vm_debug.h"
#include "vm_time.h"
namespace UMC
{
MPEG4EncoderParams::MPEG4EncoderParams() {
ippsZero_8u((Ipp8u*)(&m_Param), sizeof(m_Param));
m_Param.quantIVOP = 4;
m_Param.quantPVOP = 4;
m_Param.quantBVOP = 6;
m_Param.IVOPdist = 300;
m_Param.PVOPsearchWidth = -15;
m_Param.PVOPsearchHeight = 15;
m_Param.BVOPsearchWidthForw = 15;
m_Param.BVOPsearchHeightForw = 15;
m_Param.BVOPsearchWidthBack = 15;
m_Param.BVOPsearchHeightBack = 15;
m_Param.MEalgorithm = 1;
m_Param.MEaccuracy = 2;
m_Param.obmc_disable = 1;
m_Param.RoundingControl = 1;
m_Param.SceneChangeThreshold = 45;
m_Param.bsBuffer = (Ipp8u*)1;
m_Param.bsBuffSize = 1; // encoder will not allocate buffer
m_Param.padType = 0; // set 1 for QuickTime(tm) and 2 for DivX (tm) v. >= 5
m_Param.TimeResolution = 30;
m_Param.TimeIncrement = 1;
}
MPEG4VideoEncoder::MPEG4VideoEncoder()
{
m_IsInit = false;
}
MPEG4VideoEncoder::~MPEG4VideoEncoder()
{
Close();
}
Status MPEG4VideoEncoder::AllocateBuffers()
{
Status status = UMC_OK;
int i;
// allocate only frame memory, may be extended for whole buffers
for (i = 0; i < mp4enc->mPlanes; i ++)
mp4enc->mFrame[i].mid = 0;
for (i = 0; i < mp4enc->mPlanes; i ++) {
status = m_pMemoryAllocator->Alloc(&mp4enc->mFrame[i].mid, mp4enc->mLumaPlaneSize + mp4enc->mChromaPlaneSize + mp4enc->mChromaPlaneSize, UMC_ALLOC_PERSISTENT);
if (status != UMC_OK)
return status;
}
return status;
}
Status MPEG4VideoEncoder::FreeBuffers()
{
Status status = UMC_OK;
int i;
for (i = 0; i < mp4enc->mPlanes; i ++) {
if (mp4enc->mFrame[i].mid)
status = m_pMemoryAllocator->Free(mp4enc->mFrame[i].mid);
if (status != UMC_OK)
return status;
}
return status;
}
void MPEG4VideoEncoder::LockBuffers()
{
int i;
for (i = 0; i < mp4enc->mPlanes; i ++) {
mp4enc->mFrame[i].ap = (Ipp8u*)m_pMemoryAllocator->Lock(mp4enc->mFrame[i].mid);
mp4enc->mFrame[i].pY = mp4enc->mFrame[i].ap + mp4enc->mExpandSizeA + mp4enc->mExpandSizeA * mp4enc->mStepLuma;
mp4enc->mFrame[i].pU = mp4enc->mFrame[i].ap + mp4enc->mLumaPlaneSize + (mp4enc->mExpandSizeA >> 1) + (mp4enc->mExpandSizeA >> 1) * mp4enc->mStepChroma;
mp4enc->mFrame[i].pV = mp4enc->mFrame[i].ap + mp4enc->mLumaPlaneSize + mp4enc->mChromaPlaneSize + (mp4enc->mExpandSizeA >> 1) + (mp4enc->mExpandSizeA >> 1) * mp4enc->mStepChroma;
}
}
Status MPEG4VideoEncoder::UnlockBuffers()
{
Status status = UMC_OK;
int i;
for (i = 0; i < mp4enc->mPlanes; i ++) {
status = m_pMemoryAllocator->Unlock(mp4enc->mFrame[i].mid);
if (status != UMC_OK)
return status;
}
return status;
}
Status MPEG4VideoEncoder::Reset()
{
return Init(&m_Param);
//return UMC_ERR_NOT_IMPLEMENTED;
}
Status MPEG4VideoEncoder::SetParams(BaseCodecParams* baseParams)
{
VideoEncoderParams *bParam = DynamicCast<VideoEncoderParams, BaseCodecParams>(baseParams);
if (bParam == NULL)
return UMC_ERR_UNSUPPORTED;
// only BitRate and FrameRate could be changed
if (bParam->info.bitrate == m_Param.info.bitrate && bParam->info.framerate == m_Param.info.framerate)
return UMC_ERR_UNSUPPORTED;
m_Param.info.bitrate = bParam->info.bitrate;
m_Param.info.framerate = bParam->info.framerate;
mp4enc->ResetRC(m_Param.info.bitrate, m_Param.info.framerate);
return UMC_OK;
//return UMC_ERR_NOT_IMPLEMENTED;
}
Status MPEG4VideoEncoder::Init(BaseCodecParams* init)
{
MPEG4EncoderParams *pParam = DynamicCast<MPEG4EncoderParams>(init);
VideoEncoderParams *vParam = DynamicCast<VideoEncoderParams>(init);
int numThreads;
if (vParam == NULL && pParam == NULL)
return UMC_ERR_NULL_PTR;
if (m_IsInit)
Close();
mp4enc = new MPEG4_ENC::ippVideoEncoderMPEG4;
if (!mp4enc)
return UMC_ERR_ALLOC;
if (pParam == NULL) {
m_Param.m_Param.quant_type = 0;
m_Param.m_Param.quantIVOP = 4;
m_Param.m_Param.quantPVOP = 4;
m_Param.m_Param.quantBVOP = 6;
m_Param.m_Param.short_video_header = 0;
m_Param.m_Param.IVOPdist = 300;
m_Param.m_Param.BVOPdist = 0;
m_Param.m_Param.PVOPsearchWidth = -15;
m_Param.m_Param.PVOPsearchHeight = 15;
m_Param.m_Param.BVOPsearchWidthForw = 15;
m_Param.m_Param.BVOPsearchHeightForw = 15;
m_Param.m_Param.BVOPsearchWidthBack = 15;
m_Param.m_Param.BVOPsearchHeightBack = 15;
m_Param.m_Param.MEalgorithm = 1;
m_Param.m_Param.MEaccuracy = 2;
m_Param.m_Param.ME4mv = 0;
m_Param.m_Param.obmc_disable = 1;
m_Param.m_Param.RoundingControl = 1;
m_Param.m_Param.calcPSNR = 0;
m_Param.m_Param.SceneChangeThreshold = 45;
m_Param.m_Param.insertGOV = 0;
m_Param.m_Param.repeatHeaders = 0;
m_Param.m_Param.resync = 0;
m_Param.m_Param.VideoPacketLenght = 8192;
m_Param.m_Param.data_partitioned = 0;
m_Param.m_Param.reversible_vlc = 0;
m_Param.m_Param.interlaced = 0;
m_Param.m_Param.top_field_first = 1;
m_Param.m_Param.alternate_vertical_scan_flag = 1;
m_Param.m_Param.interlacedME = 0;
m_Param.m_Param.sprite_enable = 0;
m_Param.m_Param.no_of_sprite_warping_points = 0;
m_Param.m_Param.sprite_warping_accuracy = 0;
m_Param.m_Param.sprite_brightness_change = 0;
m_Param.m_Param.sprite_left_coordinate = 0;
m_Param.m_Param.sprite_top_coordinate = 0;
m_Param.m_Param.sprite_width = 0;
m_Param.m_Param.sprite_height = 0;
m_Param.m_Param.warping_mv_code_du = NULL;
m_Param.m_Param.warping_mv_code_dv = NULL;
m_Param.m_Param.brightness_change_factor = NULL;
m_Param.m_Param.load_intra_quant_mat = 0;
m_Param.m_Param.load_intra_quant_mat_len = 0;
m_Param.m_Param.load_nonintra_quant_mat = 0;
m_Param.m_Param.load_nonintra_quant_mat_len = 0;
m_Param.m_Param.bsBuffer = (Ipp8u*)1;
m_Param.m_Param.bsBuffSize = 1; // encoder will not allocate buffer
m_Param.m_Param.padType = 0; // set 1 for QuickTime(tm) and 2 for DivX (tm) v. >= 5
m_Param.m_Param.Width = vParam->info.clip_info.width;
m_Param.m_Param.Height = vParam->info.clip_info.height;
if (vParam->info.bitrate <= 0) {
m_Param.m_Param.RateControl = 0;
m_Param.m_Param.BitRate = 0;
} else {
m_Param.m_Param.RateControl = 1;
m_Param.m_Param.BitRate = vParam->info.bitrate;
}
m_Param.info.framerate = vParam->info.framerate;
if (vParam->info.framerate > 0 && (vParam->info.framerate == (Ipp32s)vParam->info.framerate)) {
m_Param.m_Param.TimeResolution = (Ipp32s)vParam->info.framerate;
m_Param.m_Param.TimeIncrement = 1;
} else {
if (vParam->info.framerate >= 23.976 && vParam->info.framerate < 24) {
m_Param.m_Param.TimeResolution = 24000;
m_Param.m_Param.TimeIncrement = 1001;
} else if (vParam->info.framerate >= 29.97 && vParam->info.framerate < 30) {
m_Param.m_Param.TimeResolution = 30000;
m_Param.m_Param.TimeIncrement = 1001;
} else {
m_Param.m_Param.TimeResolution = 30;
m_Param.m_Param.TimeIncrement = 1;
m_Param.info.framerate = 30;
}
}
m_Param.info.clip_info.width = vParam->info.clip_info.width;
m_Param.info.clip_info.height = vParam->info.clip_info.height;
//m_Param.numFramesToEncode = vParam->numFramesToEncode;
m_Param.info.bitrate = vParam->info.bitrate;
} else {
m_Param = *pParam;
// override MPEG-4 params if base params are valid
if (m_Param.info.clip_info.width && m_Param.info.clip_info.height) {
m_Param.m_Param.Width = m_Param.info.clip_info.width;
m_Param.m_Param.Height = m_Param.info.clip_info.height;
}
if (m_Param.info.framerate > 0) {
if (m_Param.info.framerate == (Ipp32s)m_Param.info.framerate) {
m_Param.m_Param.TimeResolution = (Ipp32s)m_Param.info.framerate;
m_Param.m_Param.TimeIncrement = 1;
} else {
if (m_Param.info.framerate >= 23.976 && m_Param.info.framerate < 24) {
m_Param.m_Param.TimeResolution = 24000;
m_Param.m_Param.TimeIncrement = 1001;
} else if (m_Param.info.framerate >= 29.97 && m_Param.info.framerate < 30) {
m_Param.m_Param.TimeResolution = 30000;
m_Param.m_Param.TimeIncrement = 1001;
}
}
} else
m_Param.info.framerate = m_Param.m_Param.TimeResolution / m_Param.m_Param.TimeIncrement;
if (m_Param.info.bitrate > 0) {
if (m_Param.m_Param.RateControl == 0)
m_Param.m_Param.RateControl = 1;
m_Param.m_Param.BitRate = m_Param.info.bitrate;
}
}
numThreads = vParam->numThreads;
m_Param.m_Param.profile_and_level = (Ipp8u)((vParam->profile << 4) + (vParam->level & 15));
if (m_Param.m_Param.profile_and_level == 0)
m_Param.m_Param.profile_and_level = 1;
Ipp32s mp4status = mp4enc->Init(&m_Param.m_Param, numThreads);
if (mp4status == MPEG4_ENC::MP4_STS_ERR_PARAM)
return UMC_ERR_INIT;
if (mp4status == MPEG4_ENC::MP4_STS_ERR_NOMEM)
return UMC_ERR_ALLOC;
m_FrameCount = 0;
if (m_Param.m_Param.BVOPdist) {
bTime = new Ipp64f [m_Param.m_Param.BVOPdist];
if (!bTime)
return UMC_ERR_ALLOC;
}
bTimePos = 0;
gTime = 0.0;
iTime = 1.0 / vParam->info.framerate;
// create default memory allocator if not exist
Status status = BaseCodec::Init(init);
if (status != UMC_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -