📄 htrencwrapper.cpp
字号:
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- In the event of publication, the following notice is applicable: --
-- --
-- (C) COPYRIGHT 2005 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced on all copies. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Wrapper for Hantro Encoder for use in DirectShow integration
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of context
1. Include headers
2. Module defines
3. CHantroEncoderWrapper class
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "stdafx.h"
#include <stdio.h>
#include "htrencwrapper.h"
/*------------------------------------------------------------------------------
2. Module defines
------------------------------------------------------------------------------*/
#define HTRENCW_MIN_IMAGE_WIDTH 96
#define HTRENCW_MAX_IMAGE_WIDTH 640
#define HTRENCW_MOD_IMAGE_WIDTH 4
#define HTRENCW_MIN_IMAGE_HEIGHT 96
#define HTRENCW_MAX_IMAGE_HEIGHT 480
#define HTRENCW_MOD_IMAGE_HEIGHT 1
#define HTRENCW_MIN_BITRATE 16000
#define HTRENCW_MAX_BITRATE 16384000
#define HTRENCW_MIN_FRAMERATE 1
#define HTRENCW_MAX_FRAMERATE 30
#define CHECK_PARAMETER(param,min,max,mod) \
( (min) >= 0 && (param) < (min) || \
(max) >= 0 && (param) > (max) || \
(mod) > 1 && (param) % (mod) )
#define HTRENCW_DEBUG printf
#define HTRENCW_DEBUG_EXTRA /*printf*/
/*------------------------------------------------------------------------------
3. CHantroEncoderWrapper class
------------------------------------------------------------------------------*/
HRESULT CHantroEncoderWrapper::GetMinOutputStreamSize( Settings* pSettings, LONG* pOutputStreamSize )
{
return GetProfileAndLevel( pSettings, NULL, pOutputStreamSize );
}
HRESULT CHantroEncoderWrapper::ValidateSettings( Settings* pSettings )
{
// Validate video type
if( pSettings->videoType != VIDEOTYPE_MPEG4 && pSettings->videoType != VIDEOTYPE_H263 )
{
HTRENCW_DEBUG( "CHantroEncoderWrapper::ValidateParameters: FAILED, unkown video type!\n" );
return E_INVALIDARG;
}
// Validate video size. H.263 limitations are checked when deriving the profile&level.
if( CHECK_PARAMETER( pSettings->frameWidth, HTRENCW_MIN_IMAGE_WIDTH,
HTRENCW_MAX_IMAGE_WIDTH,
HTRENCW_MOD_IMAGE_WIDTH ))
{
HTRENCW_DEBUG( "CHantroEncoderWrapper::ValidateParameters: FAILED, invalid image width!\n" );
return E_INVALIDARG;
}
if( CHECK_PARAMETER( pSettings->frameHeight, HTRENCW_MIN_IMAGE_HEIGHT,
HTRENCW_MAX_IMAGE_HEIGHT,
HTRENCW_MOD_IMAGE_HEIGHT ))
{
HTRENCW_DEBUG( "CHantroEncoderWrapper::ValidateParameters: FAILED, invalid image height!\n" );
return E_INVALIDARG;
}
// Validate bitrate settings
if( CHECK_PARAMETER( pSettings->bitrate, HTRENCW_MIN_BITRATE,
HTRENCW_MAX_BITRATE,
0 ))
{
HTRENCW_DEBUG( "CHantroEncoderWrapper::ValidateParameters: FAILED, invalid bitare!\n" );
return E_INVALIDARG;
}
// Validate framerate settings
if( CHECK_PARAMETER( pSettings->frameRate, HTRENCW_MIN_FRAMERATE,
HTRENCW_MAX_FRAMERATE,
0 ))
{
HTRENCW_DEBUG( "CHantroEncoderWrapper::ValidateParameters: FAILED, invalid frameRate=%d!\n", pSettings->frameRate );
return E_INVALIDARG;
}
return S_OK;
}
HRESULT CHantroEncoderWrapper::GetProfileAndLevel( Settings* pSettings,
MP4EncProfileAndLevel* pProfileAndLevel,
LONG* pOutputStreamSize )
{
u32 numberOfMBs;
u32 MBps; // macroblocks per second
u32 vbvBufSize = 0;
MP4EncProfileAndLevel profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_0;
u32 width = pSettings->frameWidth;
u32 height = pSettings->frameHeight;
if( width % 16 != 0 ) width += 16;
if( height % 16 != 0 ) height += 16;
u32 frameRateNum = pSettings->frameRate;
u32 frameRateDenom = 1;
// adjust H.263 framerate
if( pSettings->videoType == VIDEOTYPE_H263 )
{
frameRateNum *= 1000;
frameRateDenom *= 1001;
}
numberOfMBs = (width / 16) * (height / 16);
MBps = numberOfMBs*frameRateNum/frameRateDenom;
switch( pSettings->videoType )
{
case VIDEOTYPE_MPEG4:
if( numberOfMBs <= 99 && pSettings->bitrate <= (64*1000) && MBps <= 1485 )
{
// Simple L0
vbvBufSize = 10;
profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_0;
}
else if( numberOfMBs <= 99 && pSettings->bitrate <= (128*1000) && MBps <= 1485 )
{
// Simple L0B
vbvBufSize = 20;
profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_0B;
}
else if( numberOfMBs <= 99 && pSettings->bitrate <= (64*1000) && MBps <= 1485 )
{
// Simple L1
vbvBufSize = 10;
profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_1;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (128*1000) && MBps <= 5940 )
{
// Simple L2
vbvBufSize = 40;
profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_2;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (384*1000) && MBps <= 11880 )
{
// Simple L3
vbvBufSize = 40;
profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_3;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (768*1000) && MBps <= 11880 )
{
// Advanced Simple L3
vbvBufSize = 40;
profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_3;
}
else if( numberOfMBs <= 792 && pSettings->bitrate <= (3000*1000) && MBps <= 23760 )
{
// Advanced Simple L4
vbvBufSize = 80;
profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_4;
}
else if( numberOfMBs <= 1200 && pSettings->bitrate <= (8000*1000) && MBps <= 36000 )
{
// Advanced Simple L5/
vbvBufSize = 112;
profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_5;
}
else
{
// error, unsupported profile and level
HTRENCW_DEBUG( "CHantroEncoderWrapper::GetProfileAndLevel: FAILED, unknown profile and level (MPEG4, numberOfMBs=%d, bitrate=%d, MBps=%d)!\n", numberOfMBs, pSettings->bitrate, MBps );
return E_INVALIDARG;
}
break;
case VIDEOTYPE_H263:
if( numberOfMBs <= 99 && pSettings->bitrate <= (64*1000) && MBps <= 1483 )
{
vbvBufSize = 5;
profileAndLevel = H263_PROFILE_0_LEVEL_10;
}
else if( numberOfMBs <= 99 && pSettings->bitrate <= (128*1000) && MBps <= 2967 )
{
vbvBufSize = 18;
profileAndLevel = H263_PROFILE_0_LEVEL_20;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (128*1000) && MBps <= 5934 )
{
vbvBufSize = 18;
profileAndLevel = H263_PROFILE_0_LEVEL_20;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (384*1000) && MBps <= 11868 )
{
vbvBufSize = 20;
profileAndLevel = H263_PROFILE_0_LEVEL_30;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (2048*1000) && MBps <= 11868 )
{
vbvBufSize = 33;
profileAndLevel = H263_PROFILE_0_LEVEL_40;
}
else if( numberOfMBs <= 396 && pSettings->bitrate <= (4096*1000) && MBps <= 11868 )
{
vbvBufSize = 64;
profileAndLevel = H263_PROFILE_0_LEVEL_50;
}
else if( numberOfMBs <= 720 && pSettings->bitrate <= (8192*1000) && MBps <= 21578 )
{
vbvBufSize = 99;
profileAndLevel = H263_PROFILE_0_LEVEL_60;
}
else if( numberOfMBs <= 1200 && pSettings->bitrate <= (16384*1000) && MBps <= 35964 )
{
vbvBufSize = 256;
profileAndLevel = H263_PROFILE_0_LEVEL_70;
}
else
{
// error, unsupported profile and level
HTRENCW_DEBUG( "CHantroEncoderWrapper::GetProfileAndLevel: FAILED, unknown profile and level (H263, numberOfMBs=%d, bitrate=%d, MBps=%d)!\n", numberOfMBs, pSettings->bitrate, MBps );
return E_INVALIDARG;
}
break;
default:
// error, unsupported profile and level
HTRENCW_DEBUG( "CHantroEncoderWrapper::GetProfileAndLevel: FAILED, invalid video type!\n" );
return E_INVALIDARG;
break;
}
// Validate H.263 size based on profile&level
bool isCIF = width==352 && height==288;
bool isQCIF = width==176 && height==144;
bool isSQCIF = width==128 && height== 96;
bool isLowH263 = profileAndLevel == H263_PROFILE_0_LEVEL_10 ||
profileAndLevel == H263_PROFILE_0_LEVEL_20 ||
profileAndLevel == H263_PROFILE_0_LEVEL_30 ||
profileAndLevel == H263_PROFILE_0_LEVEL_40;
// If necessary, promote H.263 profile&level to allow arbritary size
if( isLowH263 && !isCIF && !isQCIF && !isSQCIF )
{
profileAndLevel = H263_PROFILE_0_LEVEL_50;
vbvBufSize = 64;
}
if( pOutputStreamSize != NULL )
*pOutputStreamSize = vbvBufSize * (16384/8);
if( pProfileAndLevel != NULL )
*pProfileAndLevel = profileAndLevel;
return S_OK;
}
LONG CHantroEncoderWrapper::CalculateQP( Settings* pSettings )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -