Compare commits

...

15 Commits

Author SHA1 Message Date
dongzha
181bb110f1 Merge pull request #1347 from ruil2/ltrv1.1.1
update spatial picture when abnormal exit
2014-09-11 14:40:46 +08:00
ruil2
044f3f9ea5 update spatial picture when abnormal exit 2014-09-11 13:12:39 +08:00
lyao2
c14655358c Merge pull request #1336 from ruil2/deliveryv1.1.1
fix bug that iMaxSpatialBitrate is not correct assigned
2014-09-05 15:28:22 +08:00
ruil2
1f60e982b3 Merge pull request #1337 from lyao2/fixppsbug_111
fix pps caused death loop issue
2014-09-05 15:20:43 +08:00
lyao2
10464072e9 fix pps caused death loop issue 2014-09-05 14:22:38 +08:00
lyao2
8c3d6f0385 update SHA1Table 2014-09-05 14:05:14 +08:00
lyao2
deedcf1ebb fix bug that iMaxSpatialBitrate is not correct assigned 2014-09-05 13:50:18 +08:00
huili2
4a95357823 Merge pull request #1334 from ruil2/deliveryv1.1.1
modify delivery status interface
2014-09-05 13:49:02 +08:00
ruil2
ad48fbaee1 modify delivery status interface 2014-09-05 13:21:17 +08:00
ruil2
d7cdc0a232 Merge pull request #1332 from huili2/print_ver111
modify version info in enc/dec
2014-09-05 13:16:58 +08:00
huili2
f19e903f9d modify version info in enc/dec 2014-09-04 20:19:52 -07:00
dongzha
b350a8172c Merge pull request #1329 from huili2/ps_ne_deal_v1.1.1
when sps/pps non exist, return dsNoParamSets
2014-09-05 10:43:52 +08:00
dongzha
6cde6af024 Merge pull request #1326 from ruil2/ltrv1.1.1
add UT for LTR setopton and fix crash issue
2014-09-03 15:28:22 +08:00
ruil2
a2c5209d91 avoid LTR reference frames overflow 2014-09-03 14:10:19 +08:00
ruil2
67e58e7f39 add UT for LTR setopton and fix crash issue 2014-09-03 13:30:57 +08:00
13 changed files with 8714 additions and 8637 deletions

View File

@@ -180,7 +180,7 @@ typedef struct {
typedef struct {
bool bEnableLongTermReference; // 1: on, 0: off
int iLTRRefNum;
}SLTRConfig;
} SLTRConfig;
typedef struct {
unsigned int
uiSliceMbNum[MAX_SLICES_NUM_TMP]; //here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
@@ -425,9 +425,9 @@ typedef struct TagLevelInfo {
} SLevelInfo;
typedef struct TagDeliveryStatus {
int iDropNum; //the number of video frames that are dropped continuously before delivery to encoder, which is used by screen content.
int iDropFrameType; // the frame type that is dropped
int iDropFrameSize; // the frame size that is dropped
bool bDeliveryFlag; //0: the previous frame isn't delivered,1: the previous frame is delivered
int iDropFrameType; // the frame type that is dropped; reserved
int iDropFrameSize; // the frame size that is dropped; reserved
} SDeliveryStatus;
typedef struct TagDecoderCapability {

View File

@@ -227,7 +227,8 @@ void CWelsDecoder::UninitDecoder (void) {
// the return value of this function is not suitable, it need report failure info to upper layer.
void CWelsDecoder::InitDecoder (void) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder()..");
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder(), openh264 codec version = %s",
VERSION_NUMBER);
m_pDecContext = (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
@@ -278,6 +279,8 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
if (m_pWelsTrace) {
WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
m_pWelsTrace->SetTraceCallback (callback);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::SetOption(), openh264 codec version = %s.",
VERSION_NUMBER);
}
return cmResultSuccess;
} else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
@@ -480,7 +483,7 @@ using namespace WelsDec;
* WelsGetDecoderCapability
* @return: DecCapability information
*/
int WelsGetDecoderCapability(SDecoderCapability* pDecCapability) {
int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {
memset (pDecCapability, 0, sizeof (SDecoderCapability));
pDecCapability->iProfileIdc = 66; //Baseline
pDecCapability->iProfileIop = 0xE0; //11100000b

View File

@@ -64,165 +64,165 @@ namespace WelsEnc {
* reference list for each quality layer in SVC
*/
typedef struct TagRefList {
SPicture* pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t
SPicture* pLongRefList[1 + MAX_REF_PIC_COUNT]; // reference list 1 - int32_t
SPicture* pNextBuffer;
SPicture* pRef[1 + MAX_REF_PIC_COUNT]; // plus 1 for swap intend
uint8_t uiShortRefCount;
uint8_t uiLongRefCount; // dependend on pRef pic module
SPicture* pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t
SPicture* pLongRefList[1 + MAX_REF_PIC_COUNT]; // reference list 1 - int32_t
SPicture* pNextBuffer;
SPicture* pRef[1 + MAX_REF_PIC_COUNT]; // plus 1 for swap intend
uint8_t uiShortRefCount;
uint8_t uiLongRefCount; // dependend on pRef pic module
} SRefList;
typedef struct TagLTRState {
// LTR mark feedback
uint32_t uiLtrMarkState; // LTR mark state, indicate whether there is a LTR mark feedback unsolved
int32_t iLtrMarkFbFrameNum;// the unsolved LTR mark feedback, the marked iFrameNum feedback from decoder
uint32_t uiLtrMarkState; // LTR mark state, indicate whether there is a LTR mark feedback unsolved
int32_t iLtrMarkFbFrameNum;// the unsolved LTR mark feedback, the marked iFrameNum feedback from decoder
// LTR used as recovery reference
int32_t iLastRecoverFrameNum; // reserve the last LTR or IDR recover iFrameNum
int32_t
iLastCorFrameNumDec; // reserved the last correct position in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
int32_t
iCurFrameNumInDec; // current iFrameNum in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
int32_t iLastRecoverFrameNum; // reserve the last LTR or IDR recover iFrameNum
int32_t
iLastCorFrameNumDec; // reserved the last correct position in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
int32_t
iCurFrameNumInDec; // current iFrameNum in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
// LTR mark
int32_t iLTRMarkMode; // direct mark or delay mark
int32_t iLTRMarkSuccessNum; //successful marked num, for mark mode switch
int32_t iCurLtrIdx;// current int32_t term reference index to mark
int32_t iLastLtrIdx[MAX_TEMPORAL_LAYER_NUM];
int32_t iSceneLtrIdx;// related to Scene LTR, used by screen content
int32_t iLTRMarkMode; // direct mark or delay mark
int32_t iLTRMarkSuccessNum; //successful marked num, for mark mode switch
int32_t iCurLtrIdx;// current int32_t term reference index to mark
int32_t iLastLtrIdx[MAX_TEMPORAL_LAYER_NUM];
int32_t iSceneLtrIdx;// related to Scene LTR, used by screen content
uint32_t uiLtrMarkInterval;// the interval from the last int32_t term pRef mark
uint32_t uiLtrMarkInterval;// the interval from the last int32_t term pRef mark
bool bLTRMarkingFlag; //decide whether current frame marked as LTR
bool bLTRMarkEnable; //when LTR is confirmed and the interval is no smaller than the marking period
bool bReceivedT0LostFlag; // indicate whether a t0 lost feedback is recieved, for LTR recovery
bool bLTRMarkingFlag; //decide whether current frame marked as LTR
bool bLTRMarkEnable; //when LTR is confirmed and the interval is no smaller than the marking period
bool bReceivedT0LostFlag; // indicate whether a t0 lost feedback is recieved, for LTR recovery
} SLTRState;
typedef struct TagSpatialPicIndex {
SPicture* pSrc; // I420 based and after color space converted
int32_t iDid; // dependency id
SPicture* pSrc; // I420 based and after color space converted
int32_t iDid; // dependency id
} SSpatialPicIndex;
typedef struct TagStrideTables {
int32_t* pStrideDecBlockOffset[MAX_DEPENDENCY_LAYER][2]; // [iDid][tid==0][24 x 4]: luma+chroma= 24 x 4
int32_t* pStrideEncBlockOffset[MAX_DEPENDENCY_LAYER]; // [iDid][24 x 4]: luma+chroma= 24 x 4
int16_t* pMbIndexX[MAX_DEPENDENCY_LAYER]; // [iDid][iMbX]: map for iMbX in each spatial layer coding
int16_t* pMbIndexY[MAX_DEPENDENCY_LAYER]; // [iDid][iMbY]: map for iMbY in each spatial layer coding
int32_t* pStrideDecBlockOffset[MAX_DEPENDENCY_LAYER][2]; // [iDid][tid==0][24 x 4]: luma+chroma= 24 x 4
int32_t* pStrideEncBlockOffset[MAX_DEPENDENCY_LAYER]; // [iDid][24 x 4]: luma+chroma= 24 x 4
int16_t* pMbIndexX[MAX_DEPENDENCY_LAYER]; // [iDid][iMbX]: map for iMbX in each spatial layer coding
int16_t* pMbIndexY[MAX_DEPENDENCY_LAYER]; // [iDid][iMbY]: map for iMbY in each spatial layer coding
} SStrideTables;
typedef struct TagWelsEncCtx {
SLogContext sLogCtx;
SLogContext sLogCtx;
// Input
SWelsSvcCodingParam* pSvcParam; // SVC parameter, WelsSVCParamConfig in svc_param_settings.h
SWelsSliceBs* pSliceBs; // bitstream buffering for various slices, [uiSliceIdx]
SWelsSvcCodingParam* pSvcParam; // SVC parameter, WelsSVCParamConfig in svc_param_settings.h
SWelsSliceBs* pSliceBs; // bitstream buffering for various slices, [uiSliceIdx]
int32_t* pSadCostMb;
/* MVD cost tables for Inter MB */
int32_t iMvRange;
uint16_t* pMvdCostTable; //[52]; // adaptive to spatial layers
int32_t iMvdCostTableSize; //the size of above table
int32_t iMvdCostTableStride; //the stride of above table
SMVUnitXY*
pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer
int8_t*
pRefIndexBlock4x4; // (*pRefIndexBlock4x4[2])[MB_BLOCK8x8_NUM]; // for store each 4x4 blocks' pRef index, the two swap after different d layer
int8_t* pNonZeroCountBlocks; // (*pNonZeroCountBlocks)[MB_LUMA_CHROMA_BLOCK4x4_NUM];
int8_t*
pIntra4x4PredModeBlocks; // (*pIntra4x4PredModeBlocks)[INTRA_4x4_MODE_NUM]; //last byte is not used; the first 4 byte is for the bottom 12,13,14,15 4x4 block intra mode, and 3 byte for (3,7,11)
int32_t* pSadCostMb;
/* MVD cost tables for Inter MB */
int32_t iMvRange;
uint16_t* pMvdCostTable; //[52]; // adaptive to spatial layers
int32_t iMvdCostTableSize; //the size of above table
int32_t iMvdCostTableStride; //the stride of above table
SMVUnitXY*
pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer
int8_t*
pRefIndexBlock4x4; // (*pRefIndexBlock4x4[2])[MB_BLOCK8x8_NUM]; // for store each 4x4 blocks' pRef index, the two swap after different d layer
int8_t* pNonZeroCountBlocks; // (*pNonZeroCountBlocks)[MB_LUMA_CHROMA_BLOCK4x4_NUM];
int8_t*
pIntra4x4PredModeBlocks; // (*pIntra4x4PredModeBlocks)[INTRA_4x4_MODE_NUM]; //last byte is not used; the first 4 byte is for the bottom 12,13,14,15 4x4 block intra mode, and 3 byte for (3,7,11)
SMB** ppMbListD; // [MAX_DEPENDENCY_LAYER];
SStrideTables* pStrideTab; // stride tables for internal coding used
SWelsFuncPtrList* pFuncList;
SMB** ppMbListD; // [MAX_DEPENDENCY_LAYER];
SStrideTables* pStrideTab; // stride tables for internal coding used
SWelsFuncPtrList* pFuncList;
SSliceThreading* pSliceThreading;
SSliceThreading* pSliceThreading;
// SSlice context
SSliceCtx* pSliceCtxList;// slice context table for each dependency quality layer
SSliceCtx* pSliceCtxList;// slice context table for each dependency quality layer
// pointers
SPicture* pEncPic; // pointer to current picture to be encoded
SPicture* pDecPic; // pointer to current picture being reconstructed
SPicture* pRefPic; // pointer to current reference picture
SPicture* pEncPic; // pointer to current picture to be encoded
SPicture* pDecPic; // pointer to current picture being reconstructed
SPicture* pRefPic; // pointer to current reference picture
SDqLayer*
pCurDqLayer; // DQ layer context used to being encoded currently, for reference base layer to refer: pCurDqLayer->pRefLayer if applicable
SDqLayer** ppDqLayerList; // overall DQ layers encoded for storage
SDqLayer*
pCurDqLayer; // DQ layer context used to being encoded currently, for reference base layer to refer: pCurDqLayer->pRefLayer if applicable
SDqLayer** ppDqLayerList; // overall DQ layers encoded for storage
SRefList** ppRefPicListExt; // reference picture list for SVC
SPicture* pRefList0[16];
SLTRState* pLtr;//[MAX_DEPENDENCY_LAYER];
bool bCurFrameMarkedAsSceneLtr;
SRefList** ppRefPicListExt; // reference picture list for SVC
SPicture* pRefList0[16];
SLTRState* pLtr;//[MAX_DEPENDENCY_LAYER];
bool bCurFrameMarkedAsSceneLtr;
// Derived
int32_t iCodingIndex;
int32_t iFrameIndex; // count how many frames elapsed during coding context currently
int32_t iFrameNum; // current frame number coding
int32_t iPOC; // frame iPOC
EWelsSliceType eSliceType; // currently coding slice type
EWelsNalUnitType eNalType; // NAL type
EWelsNalRefIdc eNalPriority; // NAL_Reference_Idc currently
EWelsNalRefIdc eLastNalPriority; // NAL_Reference_Idc in last frame
uint8_t iNumRef0;
int32_t iCodingIndex;
int32_t iFrameIndex; // count how many frames elapsed during coding context currently
int32_t iFrameNum; // current frame number coding
int32_t iPOC; // frame iPOC
EWelsSliceType eSliceType; // currently coding slice type
EWelsNalUnitType eNalType; // NAL type
EWelsNalRefIdc eNalPriority; // NAL_Reference_Idc currently
EWelsNalRefIdc eLastNalPriority; // NAL_Reference_Idc in last frame
uint8_t iNumRef0;
uint8_t uiDependencyId; // Idc of dependecy layer to be coded
uint8_t uiTemporalId; // Idc of temporal layer to be coded
bool bNeedPrefixNalFlag; // whether add prefix nal
bool bEncCurFrmAsIdrFlag;
uint8_t uiDependencyId; // Idc of dependecy layer to be coded
uint8_t uiTemporalId; // Idc of temporal layer to be coded
bool bNeedPrefixNalFlag; // whether add prefix nal
bool bEncCurFrmAsIdrFlag;
// Rate control routine
SWelsSvcRc* pWelsSvcRc;
int32_t iSkipFrameFlag; //_GOM_RC_
int32_t iGlobalQp; // global qp
SWelsSvcRc* pWelsSvcRc;
int32_t iSkipFrameFlag; //_GOM_RC_
int32_t iGlobalQp; // global qp
// VAA
SVAAFrameInfo* pVaa; // VAA information of reference
CWelsPreProcess* pVpp;
SVAAFrameInfo* pVaa; // VAA information of reference
CWelsPreProcess* pVpp;
SWelsSPS* pSpsArray; // MAX_SPS_COUNT by standard compatible
SWelsSPS* pSps;
SWelsPPS* pPPSArray; // MAX_PPS_COUNT by standard compatible
SWelsPPS* pPps;
/* SVC only */
SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible
SSubsetSps* pSubsetSps;
int32_t iSpsNum; // number of pSps used
int32_t iPpsNum; // number of pPps used
SWelsSPS* pSpsArray; // MAX_SPS_COUNT by standard compatible
SWelsSPS* pSps;
SWelsPPS* pPPSArray; // MAX_PPS_COUNT by standard compatible
SWelsPPS* pPps;
/* SVC only */
SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible
SSubsetSps* pSubsetSps;
int32_t iSpsNum; // number of pSps used
int32_t iPpsNum; // number of pPps used
// Output
SWelsEncoderOutput* pOut; // for NAL raw pData (need allocating memory for sNalList internal)
uint8_t* pFrameBs; // restoring bitstream pBuffer of all NALs in a frame
int32_t iFrameBsSize; // count size of frame bs in bytes allocated
int32_t iPosBsBuffer; // current writing position of frame bs pBuffer
SWelsEncoderOutput* pOut; // for NAL raw pData (need allocating memory for sNalList internal)
uint8_t* pFrameBs; // restoring bitstream pBuffer of all NALs in a frame
int32_t iFrameBsSize; // count size of frame bs in bytes allocated
int32_t iPosBsBuffer; // current writing position of frame bs pBuffer
SSpatialPicIndex sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
SSpatialPicIndex sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
bool bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
bool bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
int16_t iMaxSliceCount;// maximal count number of slices for all layers observation
int16_t iActiveThreadsNum; // number of threads active so far
int16_t iMaxSliceCount;// maximal count number of slices for all layers observation
int16_t iActiveThreadsNum; // number of threads active so far
/*
* DQ layer idc map for svc encoding, might be a better scheme than that of design before,
* can aware idc of referencing layer and that idc of successive layer to be coded
*/
/* SVC only */
SDqIdc*
pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData
/*
* DQ layer idc map for svc encoding, might be a better scheme than that of design before,
* can aware idc of referencing layer and that idc of successive layer to be coded
*/
/* SVC only */
SDqIdc*
pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData
SParaSetOffset sPSOVector;
CMemoryAlign* pMemAlign;
SParaSetOffset sPSOVector;
CMemoryAlign* pMemAlign;
#if defined(STAT_OUTPUT)
// overall stat pData, refer to SStatData in stat.h, in case avc to use stat[0][0]
SStatData sStatData [ MAX_DEPENDENCY_LAYER ] [ MAX_QUALITY_LEVEL ];
SStatSliceInfo sPerInfo;
SStatData sStatData [ MAX_DEPENDENCY_LAYER ] [ MAX_QUALITY_LEVEL ];
SStatSliceInfo sPerInfo;
#endif//STAT_OUTPUT
int32_t iEncoderError;
WELS_MUTEX mutexEncoderError;
int32_t iDropNumber;
int32_t iEncoderError;
WELS_MUTEX mutexEncoderError;
bool bDeliveryFlag;
#ifdef ENABLE_FRAME_DUMP
bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
bool bRecFlag;
bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
bool bRecFlag;
#endif
} sWelsEncCtx/*, *PWelsEncCtx*/;
}

View File

@@ -108,7 +108,7 @@ int32_t ForceCodingIDR (sWelsEncCtx* pCtx);
int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNew);
void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam);
void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer);
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx*pCtx,SLTRConfig* pLTRValue);
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest);
void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarkingFeedback);

View File

@@ -398,6 +398,8 @@ int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
pSpatialLayer->iVideoHeight = pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight;// frame height
pSpatialLayer->iSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
pSpatialLayer->iMaxSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
//multi slice
pSpatialLayer->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;

View File

@@ -2680,7 +2680,6 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
//31st finish: next_spsid_in_bs == 1;
const int32_t kiEncId = kiCurEncoderParaSetId;
const bool* kpUsedIdPointer = &sParaSetOffsetVariable->bUsedParaSetIdInBs[0];
uint32_t uiNextIdInBs = sParaSetOffsetVariable->uiNextParaSetIdToUseInBs;
//update current layer's pCodingParam
@@ -2691,20 +2690,13 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
//prepare for next update:
// find the next avaibable iId
do {
++uiNextIdInBs;
if (uiNextIdInBs >= kuiMaxIdInBs) {
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
}
} while (kpUsedIdPointer[uiNextIdInBs]);
++uiNextIdInBs;
if (uiNextIdInBs >= kuiMaxIdInBs) {
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
}
// update next_id
sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
#if _DEBUG
assert (!sParaSetOffsetVariable->bUsedParaSetIdInBs[uiNextIdInBs]); //sure the next-to-use one is marked activated correctly
#endif
}
/*!
@@ -3164,6 +3156,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
pCtx->pFuncList->pMarkPic (pCtx);
if (!pCtx->pFuncList->pBuildRefList (pCtx, pCtx->iPOC, 0)) {
pCtx->pVpp->UpdateSpatialPictures (pCtx, pSvcParam, iCurTid, iDidIdx);
// Force coding IDR as followed
ForceCodingIDR (pCtx);
WelsLog (pLogCtx, WELS_LOG_WARNING,
@@ -3434,6 +3427,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
// reference picture list update
if (eNalRefIdc != NRI_PRI_LOWEST) {
if (!pCtx->pFuncList->pUpdateRefList (pCtx)) {
pCtx->pVpp->UpdateSpatialPictures (pCtx, pSvcParam, iCurTid, iDidIdx);
// Force coding IDR as followed
ForceCodingIDR (pCtx);
WelsLog (pLogCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsUpdateRefList failed. ForceCodingIDR!");
@@ -3825,10 +3819,10 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
return 0;
}
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx* pCtx, SLTRConfig* pLTRValue) {
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue) {
SWelsSvcCodingParam sConfig;
int32_t iNumRefFrame = 1;
memcpy (&sConfig, pCtx->pSvcParam, sizeof (SWelsSvcCodingParam));
memcpy (&sConfig, (*ppCtx)->pSvcParam, sizeof (SWelsSvcCodingParam));
sConfig.bEnableLongTermReference = pLTRValue->bEnableLongTermReference;
sConfig.iLTRRefNum = pLTRValue->iLTRRefNum;
int32_t uiGopSize = 1 << (sConfig.iTemporalLayerNum - 1);
@@ -3856,9 +3850,9 @@ void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx* pCtx, SLTRConfig* p
if (sConfig.iNumRefFrame > sConfig.iMaxNumRefFrame)
sConfig.iMaxNumRefFrame = sConfig.iNumRefFrame;
WelsLog (pLogCtx, WELS_LOG_WARNING, " CWelsH264SVCEncoder::SetOption enable LTR = %d,ltrnum = %d",
WelsLog (pLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable LTR = %d,ltrnum = %d",
sConfig.bEnableLongTermReference, sConfig.iLTRRefNum);
WelsEncoderParamAdjust (&pCtx, &sConfig);
WelsEncoderParamAdjust (ppCtx, &sConfig);
}
int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
SFrameBSInfo* pFrameBsInfo,

View File

@@ -709,7 +709,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
pEncCtx->iSkipFrameFlag = 1;
pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,"skip one frame");
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "skip one frame");
}
if (pWelsSvcRc->iBufferFullnessSkip < 0)
@@ -1005,8 +1005,10 @@ void WelRcPictureInitBufferBasedQp (void* pCtx) {
iMinQp = MIN_SCREEN_QP + 1;
else
iMinQp = MIN_SCREEN_QP;
pEncCtx->iGlobalQp += pEncCtx->iDropNumber;
if (pEncCtx->bDeliveryFlag)
pEncCtx->iGlobalQp -= 1;
else
pEncCtx->iGlobalQp += 2;
pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP);
}
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {

View File

@@ -315,6 +315,10 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
}
pLongRefList[0] = pShortRefList[i];
pRefList->uiLongRefCount++;
if (pRefList->uiLongRefCount > pCtx->pSvcParam->iLTRRefNum) {
SetUnref (pRefList->pLongRefList[pRefList->uiLongRefCount - 1]);
DeleteLTRFromLongList (pCtx, pRefList->uiLongRefCount - 1);
}
DeleteSTRFromShortList (pCtx, i);
}
}

View File

@@ -343,7 +343,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
m_iMaxPicWidth = pCfg->iPicWidth;
m_iMaxPicHeight = pCfg->iPicHeight;
TraceParamInfo(pCfg);
TraceParamInfo (pCfg);
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
Uninitialize();
@@ -363,7 +363,8 @@ int32_t CWelsH264SVCEncoder::Uninitialize() {
return 0;
}
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::Uninitialize()..");
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::Uninitialize(), openh264 codec version = %s.",
VERSION_NUMBER);
#ifdef REC_FRAME_COUNT
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
@@ -525,57 +526,57 @@ void CWelsH264SVCEncoder::CheckReferenceNumSetting (int32_t iNumRef) {
"doesn't support the number of reference frame(%d) change to auto select mode", iNumRef);
}
}
void CWelsH264SVCEncoder::TraceParamInfo(SEncParamExt *pParam){
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\
void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\
bEnableSpsPpsIdAddition = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\
iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d",
pParam->iUsageType,
pParam->iPicWidth,
pParam->iPicHeight,
pParam->iTargetBitrate,
pParam->iMaxBitrate,
pParam->iRCMode,
pParam->iPaddingFlag,
pParam->iTemporalLayerNum,
pParam->iSpatialLayerNum,
pParam->fMaxFrameRate,
pParam->uiIntraPeriod,
pParam->bEnableSpsPpsIdAddition,
pParam->bPrefixNalAddingCtrl,
pParam->bEnableDenoise,
pParam->bEnableBackgroundDetection,
pParam->bEnableAdaptiveQuant,
pParam->bEnableFrameSkip,
pParam->bEnableLongTermReference,
pParam->iLtrMarkPeriod,
pParam->iComplexityMode,
pParam->iNumRefFrame,
pParam->iEntropyCodingModeFlag,
pParam->uiMaxNalSize,
pParam->iLTRRefNum,
pParam->iMultipleThreadIdc,
pParam->iLoopFilterDisableIdc
);
int32_t i = 0;
while (i < pParam->iSpatialLayerNum) {
SSpatialLayerConfig* pSpatialCfg = &pParam->sSpatialLayers[i];
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iSpatialBitrate= %d; .iMaxSpatialBitrate= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.iSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\
pParam->iUsageType,
pParam->iPicWidth,
pParam->iPicHeight,
pParam->iTargetBitrate,
pParam->iMaxBitrate,
pParam->iRCMode,
pParam->iPaddingFlag,
pParam->iTemporalLayerNum,
pParam->iSpatialLayerNum,
pParam->fMaxFrameRate,
pParam->uiIntraPeriod,
pParam->bEnableSpsPpsIdAddition,
pParam->bPrefixNalAddingCtrl,
pParam->bEnableDenoise,
pParam->bEnableBackgroundDetection,
pParam->bEnableAdaptiveQuant,
pParam->bEnableFrameSkip,
pParam->bEnableLongTermReference,
pParam->iLtrMarkPeriod,
pParam->iComplexityMode,
pParam->iNumRefFrame,
pParam->iEntropyCodingModeFlag,
pParam->uiMaxNalSize,
pParam->iLTRRefNum,
pParam->iMultipleThreadIdc,
pParam->iLoopFilterDisableIdc
);
int32_t i = 0;
while (i < pParam->iSpatialLayerNum) {
SSpatialLayerConfig* pSpatialCfg = &pParam->sSpatialLayers[i];
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iSpatialBitrate= %d; .iMaxSpatialBitrate= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.iSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\
uiProfileIdc = %d;uiLevelIdc = %d",
i, pSpatialCfg->iVideoWidth,
pSpatialCfg->iVideoHeight,
pSpatialCfg->fFrameRate,
pSpatialCfg->iSpatialBitrate,
pSpatialCfg->iMaxSpatialBitrate,
pSpatialCfg->sSliceCfg.uiSliceMode,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceNum,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint,
pSpatialCfg->uiProfileIdc,
pSpatialCfg->uiLevelIdc
);
++ i;
}
i, pSpatialCfg->iVideoWidth,
pSpatialCfg->iVideoHeight,
pSpatialCfg->fFrameRate,
pSpatialCfg->iSpatialBitrate,
pSpatialCfg->iMaxSpatialBitrate,
pSpatialCfg->sSliceCfg.uiSliceMode,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceNum,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint,
pSpatialCfg->uiProfileIdc,
pSpatialCfg->uiLevelIdc
);
++ i;
}
}
/************************************************************************
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
@@ -642,7 +643,7 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
int32_t iTargetHeight = 0;
memcpy (&sEncodingParam, pOption, sizeof (SEncParamExt)); // confirmed_safe_unsafe_usage
TraceParamInfo(&sEncodingParam);
TraceParamInfo (&sEncodingParam);
#ifdef OUTPUT_BIT_STREAM
if (sEncodingParam.sSpatialLayers[sEncodingParam.iSpatialLayerNum - 1].iVideoWidth !=
m_pEncContext->pSvcParam->sDependencyLayers[m_pEncContext->pSvcParam->iSpatialLayerNum - 1].iActualWidth) {
@@ -808,7 +809,7 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
break;
case ENCODER_OPTION_LTR: {
SLTRConfig* pLTRValue = ((SLTRConfig*) (pOption));
WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, m_pEncContext, pLTRValue);
WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, &m_pEncContext, pLTRValue);
}
break;
case ENCODER_OPTION_ENABLE_SSEI: {
@@ -861,6 +862,8 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
if (m_pWelsTrace) {
WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
m_pWelsTrace->SetTraceCallback (callback);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption(), openh264 codec version = %s.",
VERSION_NUMBER);
}
}
break;
@@ -898,7 +901,7 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
break;
case ENCODER_OPTION_DELIVERY_STATUS: {
SDeliveryStatus* pValue = (static_cast<SDeliveryStatus*> (pOption));
m_pEncContext->iDropNumber = pValue->iDropNum;
m_pEncContext->bDeliveryFlag = pValue->bDeliveryFlag;
}
break;
case ENCODER_OPTION_COMPLEXITY: {

View File

@@ -1,6 +1,8 @@
#include <gtest/gtest.h>
#include "codec_def.h"
#include "codec_api.h"
#include "utils/BufferedData.h"
#include "utils/FileInputStream.h"
#include "BaseEncoderTest.h"
class EncInterfaceCallTest : public ::testing::Test, public BaseEncoderTest {
@@ -12,6 +14,9 @@ class EncInterfaceCallTest : public ::testing::Test, public BaseEncoderTest {
BaseEncoderTest::TearDown();
};
virtual void onEncodeFrame (const SFrameBSInfo& frameInfo) {
//nothing
}
//testing case
};
@@ -34,3 +39,67 @@ TEST_F (EncInterfaceCallTest, BaseParameterVerify) {
uiTraceLevel = WELS_LOG_ERROR;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &uiTraceLevel);
}
void outputData() {
}
TEST_F (EncInterfaceCallTest, SetOptionLTR) {
int iTotalFrameNum = 100;
int iFrameNum = 0;
int frameSize = 0;
int ret = cmResultSuccess;
int width = 320;
int height = 192;
SEncParamBase baseparam;
memset (&baseparam, 0, sizeof (SEncParamBase));
baseparam.iUsageType = CAMERA_VIDEO_REAL_TIME;
baseparam.fMaxFrameRate = 12;
baseparam.iPicWidth = width;
baseparam.iPicHeight = height;
baseparam.iTargetBitrate = 5000000;
encoder_->Initialize (&baseparam);
frameSize = width * height * 3 / 2;
BufferedData buf;
buf.SetLength (frameSize);
ASSERT_TRUE (buf.Length() == (size_t)frameSize);
SFrameBSInfo info;
memset (&info, 0, sizeof (SFrameBSInfo));
SSourcePicture pic;
memset (&pic, 0, sizeof (SSourcePicture));
pic.iPicWidth = width;
pic.iPicHeight = height;
pic.iColorFormat = videoFormatI420;
pic.iStride[0] = pic.iPicWidth;
pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
pic.pData[0] = buf.data();
pic.pData[1] = pic.pData[0] + width * height;
pic.pData[2] = pic.pData[1] + (width * height >> 2);
SLTRConfig config;
config.bEnableLongTermReference = true;
config.iLTRRefNum = rand() % 4;
encoder_->SetOption (ENCODER_OPTION_LTR, &config);
do {
FileInputStream fileStream;
ASSERT_TRUE (fileStream.Open ("res/CiscoVT2people_320x192_12fps.yuv"));
while (fileStream.read (buf.data(), frameSize) == frameSize) {
ret = encoder_->EncodeFrame (&pic, &info);
ASSERT_TRUE (ret == cmResultSuccess);
if (info.eFrameType != videoFrameTypeSkip && this != NULL) {
this->onEncodeFrame (info);
iFrameNum++;
}
}
} while (iFrameNum < iTotalFrameNum);
}