Merge pull request #554 from ruil2/encoder_update
add maxbitrate parameter
This commit is contained in:
commit
9d73d273ff
@ -76,6 +76,7 @@ typedef enum {
|
||||
ENCODER_OPTION_SVC_ENCODE_PARAM_EXT,
|
||||
ENCODER_OPTION_FRAME_RATE,
|
||||
ENCODER_OPTION_BITRATE,
|
||||
ENCODER_OPTION_MAX_BITRATE,
|
||||
ENCODER_OPTION_INTER_SPATIAL_PRED,
|
||||
ENCODER_OPTION_RC_MODE,
|
||||
ENCODER_PADDING_PADDING,
|
||||
@ -118,6 +119,14 @@ typedef enum {
|
||||
VIDEO_CODING_LAYER = 1
|
||||
} LAYER_TYPE;
|
||||
|
||||
typedef enum {
|
||||
SPATIAL_LAYER_0 = 0,
|
||||
SPATIAL_LAYER_1 = 1,
|
||||
SPATIAL_LAYER_2 = 2,
|
||||
SPATIAL_LAYER_3 = 3,
|
||||
SPATIAL_LAYER_ALL = 4,
|
||||
} LAYER_NUM;
|
||||
|
||||
//enumerate the type of video bitstream which is provided to decoder
|
||||
typedef enum {
|
||||
VIDEO_BITSTREAM_AVC = 0,
|
||||
@ -174,6 +183,7 @@ typedef struct {
|
||||
int iVideoHeight; // video size in cy specified for a layer
|
||||
float fFrameRate; // frame rate specified for a layer
|
||||
int iSpatialBitrate; // target bitrate for a spatial layer
|
||||
int iMaxSpatialBitrate;
|
||||
unsigned int uiProfileIdc; // value of profile IDC (0 for auto-detection)
|
||||
int iDLayerQp;
|
||||
|
||||
@ -222,6 +232,7 @@ typedef struct TagEncParamExt
|
||||
/* rc control */
|
||||
bool bEnableRc;
|
||||
bool bEnableFrameSkip; // allow skipping frames to keep the bitrate within limits
|
||||
int iMaxBitrate; // max bitrate desired
|
||||
int iMaxQp;
|
||||
int iMinQp;
|
||||
|
||||
@ -300,6 +311,11 @@ typedef struct Source_Picture_s {
|
||||
long long uiTimeStamp;
|
||||
} SSourcePicture;
|
||||
|
||||
typedef struct Bitrate_Info_s{
|
||||
LAYER_NUM iLayer;
|
||||
int iBitrate; //the maximum bitrate
|
||||
}SBitrateInfo;
|
||||
|
||||
typedef struct Dump_Layer_s{
|
||||
int iLayer;
|
||||
char *pFileName;
|
||||
|
@ -75,7 +75,6 @@ typedef enum {
|
||||
cmUnsupportedData,
|
||||
} CM_RETURN;
|
||||
|
||||
|
||||
/* nal unit type */
|
||||
enum ENalUnitType {
|
||||
NAL_UNKNOWN = 0,
|
||||
|
@ -107,7 +107,7 @@ int32_t ForceCodingIDR (sWelsEncCtx* pCtx);
|
||||
*/
|
||||
int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNew);
|
||||
void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam);
|
||||
void WelsEncoderApplyBitRate(SWelsSvcCodingParam* pParam);
|
||||
void WelsEncoderApplyBitRate(SWelsSvcCodingParam* pParam,int32_t iLayer);
|
||||
|
||||
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest);
|
||||
|
||||
|
@ -149,6 +149,7 @@ static void FillDefault (SEncParamExt& param, const bool kbEnableRc) {
|
||||
param.uiFrameToBeCoded = (uint32_t) - 1; // frame to be encoded (at input frame rate)
|
||||
|
||||
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
|
||||
param.iMaxBitrate = MAX_BIT_RATE;
|
||||
#ifdef MT_ENABLED
|
||||
param.iMultipleThreadIdc = 0; // auto to detect cpu cores inside
|
||||
#else
|
||||
@ -279,7 +280,6 @@ int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam, const bool kbEnab
|
||||
pDlp->iSpatialBitrate =
|
||||
sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
|
||||
|
||||
|
||||
pDlp->iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
@ -334,6 +334,7 @@ int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
|
||||
iPaddingFlag = pCodingParam.iPaddingFlag;
|
||||
|
||||
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
|
||||
iMaxBitrate = pCodingParam.iMaxBitrate;
|
||||
|
||||
/* Denoise Control */
|
||||
bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now
|
||||
@ -406,7 +407,6 @@ int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
|
||||
pDlp->iSpatialBitrate =
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
|
||||
|
||||
|
||||
//multi slice
|
||||
pDlp->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;
|
||||
pDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
|
||||
|
@ -376,7 +376,7 @@ void WelsEncoderApplyFrameRate(SWelsSvcCodingParam* pParam)
|
||||
}
|
||||
|
||||
|
||||
void WelsEncoderApplyBitRate(SWelsSvcCodingParam* pParam)
|
||||
void WelsEncoderApplyBitRate(SWelsSvcCodingParam* pParam,int iLayer)
|
||||
{
|
||||
//TODO (Sijia): this is a temporary solution which keep the ratio between layers
|
||||
//but it is also possible to fulfill the bitrate of lower layer first
|
||||
@ -384,16 +384,30 @@ void WelsEncoderApplyBitRate(SWelsSvcCodingParam* pParam)
|
||||
SDLayerParam* pLayerParam;
|
||||
const int32_t iNumLayers = pParam->iSpatialLayerNum;
|
||||
int32_t i, iOrigTotalBitrate=0;
|
||||
//read old BR
|
||||
for (i=0;i<iNumLayers;i++) {
|
||||
iOrigTotalBitrate += pParam->sDependencyLayers[i].iSpatialBitrate;
|
||||
}
|
||||
//write new BR
|
||||
float fRatio = 0.0;
|
||||
for (i=0;i<iNumLayers;i++) {
|
||||
pLayerParam = &(pParam->sDependencyLayers[i]);
|
||||
fRatio = pLayerParam->iSpatialBitrate/(static_cast<float>(iOrigTotalBitrate));
|
||||
pLayerParam->iSpatialBitrate = static_cast<int32_t>(pParam->iTargetBitrate*fRatio);
|
||||
if(iLayer == SPATIAL_LAYER_ALL){
|
||||
if(pParam->iMaxBitrate <pParam->iTargetBitrate){
|
||||
WelsLog (NULL, WELS_LOG_WARNING,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,overall settting,TargetBitrate = %d,iMaxBitrate = %d\n",
|
||||
pParam->iTargetBitrate,pParam->iMaxBitrate);
|
||||
pParam->iMaxBitrate = pParam->iTargetBitrate;
|
||||
}
|
||||
//read old BR
|
||||
for (i=0;i<iNumLayers;i++) {
|
||||
iOrigTotalBitrate += pParam->sDependencyLayers[i].iSpatialBitrate;
|
||||
}
|
||||
//write new BR
|
||||
float fRatio = 0.0;
|
||||
for (i=0;i<iNumLayers;i++) {
|
||||
pLayerParam = &(pParam->sDependencyLayers[i]);
|
||||
fRatio = pLayerParam->iSpatialBitrate/(static_cast<float>(iOrigTotalBitrate));
|
||||
pLayerParam->iSpatialBitrate = static_cast<int32_t>(pParam->iTargetBitrate*fRatio);
|
||||
}
|
||||
}else{
|
||||
if(pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate <pParam->sSpatialLayers[iLayer].iSpatialBitrate){
|
||||
WelsLog (NULL, WELS_LOG_WARNING,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,iLayer = %d,iTargetBitrate = %d,iMaxBitrate = %d\n",
|
||||
iLayer,pParam->sSpatialLayers[iLayer].iSpatialBitrate,pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate);
|
||||
pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate = pParam->sSpatialLayers[iLayer].iSpatialBitrate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*!
|
||||
|
@ -510,8 +510,10 @@ int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSIn
|
||||
}
|
||||
|
||||
const int32_t kiEncoderReturn = EncodeFrameInternal(kpSrcPic, pBsInfo);
|
||||
|
||||
if(kiEncoderReturn != cmResultSuccess)
|
||||
return kiEncoderReturn;
|
||||
|
||||
#ifdef REC_FRAME_COUNT
|
||||
++ m_uiCountFrameNum;
|
||||
WelsLog (m_pEncContext, WELS_LOG_INFO,
|
||||
@ -521,7 +523,7 @@ int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSIn
|
||||
#ifdef DUMP_SRC_PICTURE
|
||||
DumpSrcPicture (pSrc);
|
||||
#endif // DUMP_SRC_PICTURE
|
||||
return cmResultSuccess;
|
||||
return kiEncoderReturn;
|
||||
}
|
||||
|
||||
|
||||
@ -540,7 +542,6 @@ int CWelsH264SVCEncoder::EncodeFrameInternal(const SSourcePicture* pSrcPic, SFr
|
||||
WelsLog (m_pEncContext, WELS_LOG_ERROR, "unexpected return(%d) from EncodeFrameInternal()!\n", kiEncoderReturn);
|
||||
return cmUnkonwReason;
|
||||
}
|
||||
|
||||
///////////////////for test
|
||||
#ifdef OUTPUT_BIT_STREAM
|
||||
if (pBsInfo->eOutputFrameType != videoFrameTypeInvalid && pBsInfo->eOutputFrameType != videoFrameTypeSkip) {
|
||||
@ -826,18 +827,80 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_BITRATE: { // Target bit-rate
|
||||
int32_t iValue = * ((int32_t*)pOption);
|
||||
SBitrateInfo*pInfo = (static_cast<SBitrateInfo *>(pOption));
|
||||
int32_t iBitrate = pInfo->iBitrate;
|
||||
#ifdef REC_FRAME_COUNT
|
||||
WelsLog (m_pEncContext, WELS_LOG_INFO,
|
||||
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n",
|
||||
m_uiCountFrameNum, m_iCspInternal, iValue);
|
||||
#endif//REC_FRAME_COUNT
|
||||
if (iValue<=0) {
|
||||
return cmInitParaError;
|
||||
if (iBitrate<=0) {
|
||||
WelsLog (m_pEncContext, WELS_LOG_ERROR,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,iBitrate = %d\n",iBitrate);
|
||||
return cmInitParaError;
|
||||
}
|
||||
iBitrate = WELS_CLIP3 (iBitrate, MIN_BIT_RATE, MAX_BIT_RATE);
|
||||
switch(pInfo->iLayer){
|
||||
case SPATIAL_LAYER_ALL:
|
||||
m_pEncContext->pSvcParam->iTargetBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_0:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[0].iSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_1:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[1].iSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_2:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[2].iSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_3:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[3].iSpatialBitrate = iBitrate;
|
||||
break;
|
||||
default:
|
||||
WelsLog (m_pEncContext, WELS_LOG_ERROR,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,iLayer = %d\n",pInfo->iLayer);
|
||||
return cmInitParaError;
|
||||
break;
|
||||
}
|
||||
//adjust to valid range
|
||||
m_pEncContext->pSvcParam->iTargetBitrate = WELS_CLIP3 (iValue, MIN_BIT_RATE, MAX_BIT_RATE);
|
||||
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam);
|
||||
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam,pInfo->iLayer);
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_MAX_BITRATE: { // Target bit-rate
|
||||
SBitrateInfo*pInfo = (static_cast<SBitrateInfo *>(pOption));
|
||||
int32_t iBitrate = pInfo->iBitrate;
|
||||
|
||||
#ifdef REC_FRAME_COUNT
|
||||
WelsLog (m_pEncContext, WELS_LOG_INFO,
|
||||
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n",
|
||||
m_uiCountFrameNum, m_iCspInternal, iValue);
|
||||
#endif//REC_FRAME_COUNT
|
||||
if (iBitrate<=0) {
|
||||
WelsLog (m_pEncContext, WELS_LOG_ERROR,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_MAX_BITRATE,iBitrate = %d\n",iBitrate);
|
||||
return cmInitParaError;
|
||||
}
|
||||
iBitrate = WELS_CLIP3 (iBitrate, MIN_BIT_RATE, MAX_BIT_RATE);
|
||||
switch(pInfo->iLayer){
|
||||
case SPATIAL_LAYER_ALL:
|
||||
m_pEncContext->pSvcParam->iMaxBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_0:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[0].iMaxSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_1:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[1].iMaxSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_2:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[2].iMaxSpatialBitrate = iBitrate;
|
||||
break;
|
||||
case SPATIAL_LAYER_3:
|
||||
m_pEncContext->pSvcParam->sSpatialLayers[3].iMaxSpatialBitrate = iBitrate;
|
||||
break;
|
||||
default:
|
||||
WelsLog (m_pEncContext, WELS_LOG_ERROR,"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_MAX_BITRATE,iLayer = %d\n",pInfo->iLayer);
|
||||
return cmInitParaError;
|
||||
break;
|
||||
}
|
||||
//adjust to valid range
|
||||
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam,pInfo->iLayer);
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_RC_MODE: { // 0:quality mode;1:bit-rate mode
|
||||
@ -990,7 +1053,29 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
"CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_BITRATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n",
|
||||
m_uiCountFrameNum, m_iCspInternal);
|
||||
#endif//REC_FRAME_COUNT
|
||||
* ((int32_t*)pOption) = m_pEncContext->pSvcParam->iTargetBitrate;
|
||||
SBitrateInfo*pInfo = (static_cast<SBitrateInfo *>(pOption));
|
||||
if((pInfo->iLayer!=SPATIAL_LAYER_ALL)||(pInfo->iLayer!=SPATIAL_LAYER_0)||(pInfo->iLayer!=SPATIAL_LAYER_1)||(pInfo->iLayer!=SPATIAL_LAYER_2)||(pInfo->iLayer!=SPATIAL_LAYER_3))
|
||||
return cmInitParaError;
|
||||
if(pInfo->iLayer == SPATIAL_LAYER_ALL){
|
||||
pInfo->iBitrate = m_pEncContext->pSvcParam->iTargetBitrate;
|
||||
}else{
|
||||
pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iSpatialBitrate;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_MAX_BITRATE: { // Target bit-rate
|
||||
#ifdef REC_FRAME_COUNT
|
||||
WelsLog (m_pEncContext, WELS_LOG_INFO,"CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_MAX_BITRATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n",
|
||||
m_uiCountFrameNum, m_iCspInternal);
|
||||
#endif//REC_FRAME_COUNT
|
||||
SBitrateInfo*pInfo = (static_cast<SBitrateInfo *>(pOption));
|
||||
if((pInfo->iLayer!=SPATIAL_LAYER_ALL)||(pInfo->iLayer!=SPATIAL_LAYER_0)||(pInfo->iLayer!=SPATIAL_LAYER_1)||(pInfo->iLayer!=SPATIAL_LAYER_2)||(pInfo->iLayer!=SPATIAL_LAYER_3))
|
||||
return cmInitParaError;
|
||||
if(pInfo->iLayer == SPATIAL_LAYER_ALL){
|
||||
pInfo->iBitrate = m_pEncContext->pSvcParam->iMaxBitrate;
|
||||
}else{
|
||||
pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iMaxSpatialBitrate;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user