fix conflict with master
This commit is contained in:
commit
1ac02f3002
@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0D6970BE1CA5BCFB001D88F8 /* paraset_strategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D6970BC1CA5BCFB001D88F8 /* paraset_strategy.cpp */; };
|
||||
0DD32A961B4A478B009181A1 /* wels_task_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0DD32A951B4A478B009181A1 /* wels_task_base.cpp */; };
|
||||
0DD32A991B4A4997009181A1 /* wels_task_management.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0DD32A981B4A4997009181A1 /* wels_task_management.cpp */; };
|
||||
0DD32A9C1B4A4E8F009181A1 /* wels_task_encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0DD32A9B1B4A4E8F009181A1 /* wels_task_encoder.cpp */; };
|
||||
@ -69,6 +70,8 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
04FE0684196FD9370004D7CE /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = version.h; path = ../../../common/inc/version.h; sourceTree = "<group>"; };
|
||||
0D6970BC1CA5BCFB001D88F8 /* paraset_strategy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paraset_strategy.cpp; sourceTree = "<group>"; };
|
||||
0D6970BF1CA5BD26001D88F8 /* paraset_strategy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = paraset_strategy.h; sourceTree = "<group>"; };
|
||||
0DD32A951B4A478B009181A1 /* wels_task_base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wels_task_base.cpp; sourceTree = "<group>"; };
|
||||
0DD32A971B4A47D0009181A1 /* wels_task_base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wels_task_base.h; sourceTree = "<group>"; };
|
||||
0DD32A981B4A4997009181A1 /* wels_task_management.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wels_task_management.cpp; sourceTree = "<group>"; };
|
||||
@ -281,6 +284,7 @@
|
||||
4CE446BD18BC605C0017DF25 /* nal_encap.h */,
|
||||
4CE446BF18BC605C0017DF25 /* param_svc.h */,
|
||||
4CE446C018BC605C0017DF25 /* parameter_sets.h */,
|
||||
0D6970BF1CA5BD26001D88F8 /* paraset_strategy.h */,
|
||||
4CE446C118BC605C0017DF25 /* picture.h */,
|
||||
4CE446C218BC605C0017DF25 /* picture_handle.h */,
|
||||
4CE446C418BC605C0017DF25 /* rc.h */,
|
||||
@ -329,6 +333,7 @@
|
||||
4CE446E718BC605C0017DF25 /* md.cpp */,
|
||||
4CE446E918BC605C0017DF25 /* mv_pred.cpp */,
|
||||
4CE446EA18BC605C0017DF25 /* nal_encap.cpp */,
|
||||
0D6970BC1CA5BCFB001D88F8 /* paraset_strategy.cpp */,
|
||||
4CE446EB18BC605C0017DF25 /* picture_handle.cpp */,
|
||||
4CE446ED18BC605C0017DF25 /* ratectl.cpp */,
|
||||
4CE446EE18BC605C0017DF25 /* ref_list_mgr_svc.cpp */,
|
||||
@ -475,6 +480,7 @@
|
||||
4C34067218C57D0400DFA14A /* reconstruct_neon.S in Sources */,
|
||||
0DD32A961B4A478B009181A1 /* wels_task_base.cpp in Sources */,
|
||||
F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */,
|
||||
0D6970BE1CA5BCFB001D88F8 /* paraset_strategy.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -405,6 +405,10 @@
|
||||
RelativePath="..\..\..\encoder\core\src\nal_encap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\paraset_strategy.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\picture_handle.cpp"
|
||||
>
|
||||
@ -618,6 +622,10 @@
|
||||
RelativePath="..\..\..\encoder\core\inc\parameter_sets.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\paraset_strategy.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\picture.h"
|
||||
>
|
||||
|
@ -934,14 +934,16 @@ int32_t ParseResidualBlockCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroC
|
||||
} else if (iResProperty == CHROMA_DC_U || iResProperty == CHROMA_DC_V) {
|
||||
do {
|
||||
if (pSignificantMap[j] != 0)
|
||||
sTCoeff[pScanTable[j]] = pCtx->bUseScalingList ? (pSignificantMap[j] * pDeQuantMul[0]) >> 4 :
|
||||
sTCoeff[pScanTable[j]] = pCtx->bUseScalingList ? (int16_t) ((int64_t)pSignificantMap[j] *
|
||||
(int64_t)pDeQuantMul[0] >> 4) :
|
||||
(pSignificantMap[j] * pDeQuantMul[0]);
|
||||
++j;
|
||||
} while (j < 16);
|
||||
} else { //luma ac, chroma ac
|
||||
do {
|
||||
if (pSignificantMap[j] != 0)
|
||||
sTCoeff[pScanTable[j]] = pCtx->bUseScalingList ? (pSignificantMap[j] * pDeQuantMul[pScanTable[j]] >> 4) :
|
||||
sTCoeff[pScanTable[j]] = pCtx->bUseScalingList ? (int16_t) ((int64_t)pSignificantMap[j] *
|
||||
(int64_t)pDeQuantMul[pScanTable[j]] >> 4) :
|
||||
pSignificantMap[j] * pDeQuantMul[pScanTable[j] & 0x07];
|
||||
++j;
|
||||
} while (j < 16);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define WELS_ACCESS_UNIT_WRITER_H__
|
||||
|
||||
#include "parameter_sets.h"
|
||||
#include "paraset_strategy.h"
|
||||
#include "param_svc.h"
|
||||
#include "utils.h"
|
||||
namespace WelsEnc {
|
||||
@ -92,7 +93,7 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr
|
||||
* \note Call it in case EWelsNalUnitType is PPS.
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* sPSOVector);
|
||||
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, IWelsParametersetStrategy* pParametersetStrategy);
|
||||
|
||||
/*!
|
||||
* \brief initialize pSps based on configurable parameters in svc
|
||||
@ -147,21 +148,5 @@ int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvc
|
||||
|
||||
int32_t WelsAdjustLevel (SSpatialLayerConfig* pSpatialLayer);
|
||||
|
||||
/*!
|
||||
* \brief check if the current parameter can found a presenting sps
|
||||
* \param pParam the current encoding paramter in SWelsSvcCodingParam
|
||||
* \param kbUseSubsetSps bool
|
||||
* \param iDlayerIndex int, the index of current D layer
|
||||
* \param iDlayerCount int, the number of total D layer
|
||||
* \param pSpsArray array of all the stored SPSs
|
||||
* \param pSubsetArray array of all the stored Subset-SPSs
|
||||
* \return 0 - successful
|
||||
* -1 - cannot find existing SPS for current encoder parameter
|
||||
*/
|
||||
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||
SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray,
|
||||
bool bSVCBaselayer);
|
||||
}
|
||||
#endif//WELS_ACCESS_UNIT_PARSER_H__
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "param_svc.h"
|
||||
#include "nal_encap.h"
|
||||
#include "picture.h"
|
||||
#include "paraset_strategy.h"
|
||||
#include "dq_map.h"
|
||||
#include "stat.h"
|
||||
#include "macros.h"
|
||||
@ -63,6 +64,7 @@ namespace WelsEnc {
|
||||
|
||||
class IWelsTaskManage;
|
||||
class IWelsReferenceStrategy;
|
||||
|
||||
/*
|
||||
* reference list for each quality layer in SVC
|
||||
*/
|
||||
@ -238,30 +240,7 @@ typedef struct TagWelsEncCtx {
|
||||
bool bRecFlag;
|
||||
#endif
|
||||
int64_t uiLastTimestamp;
|
||||
uint32_t GetNeededSpsNum() {
|
||||
if (0 == sPSOVector.uiNeededSpsNum) {
|
||||
sPSOVector.uiNeededSpsNum = ((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (1));
|
||||
sPSOVector.uiNeededSpsNum *= ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1));
|
||||
}
|
||||
return sPSOVector.uiNeededSpsNum;
|
||||
}
|
||||
|
||||
uint32_t GetNeededSubsetSpsNum() {
|
||||
if (0 == sPSOVector.uiNeededSubsetSpsNum) {
|
||||
sPSOVector.uiNeededSubsetSpsNum = ((pSvcParam->bSimulcastAVC) ? (0) :
|
||||
((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (pSvcParam->iSpatialLayerNum - 1)));
|
||||
}
|
||||
return sPSOVector.uiNeededSubsetSpsNum;
|
||||
}
|
||||
|
||||
uint32_t GetNeededPpsNum() {
|
||||
if (0 == sPSOVector.uiNeededPpsNum) {
|
||||
sPSOVector.uiNeededPpsNum = ((pSvcParam->eSpsPpsIdStrategy & SPS_PPS_LISTING) ? (MAX_PPS_COUNT) :
|
||||
(1 + pSvcParam->iSpatialLayerNum));
|
||||
sPSOVector.uiNeededPpsNum *= ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1));
|
||||
}
|
||||
return sPSOVector.uiNeededPpsNum;
|
||||
}
|
||||
} sWelsEncCtx/*, *PWelsEncCtx*/;
|
||||
}
|
||||
#endif//sWelsEncCtx_H__
|
||||
|
310
codec/encoder/core/inc/paraset_strategy.h
Normal file
310
codec/encoder/core/inc/paraset_strategy.h
Normal file
@ -0,0 +1,310 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WELS_PARASET_STRATEGY_H
|
||||
#define WELS_PARASET_STRATEGY_H
|
||||
|
||||
#include "param_svc.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
class IWelsParametersetStrategy {
|
||||
public:
|
||||
virtual ~IWelsParametersetStrategy() { }
|
||||
|
||||
static IWelsParametersetStrategy* CreateParametersetStrategy (EParameterSetStrategy eSpsPpsIdStrategy,
|
||||
const bool bSimulcastAVC, const int32_t kiSpatialLayerNum);
|
||||
|
||||
//virtual SParaSetOffset* GetParaSetOffset() = 0;
|
||||
|
||||
virtual int32_t GetPpsIdOffset (const int32_t iPpsId) = 0;
|
||||
virtual int32_t GetSpsIdOffset (const int32_t iPpsId, const int32_t iSpsId) = 0;
|
||||
virtual int32_t* GetSpsIdOffsetList (const int iParasetType) = 0;
|
||||
|
||||
virtual uint32_t GetAllNeededParasetNum() = 0;
|
||||
|
||||
virtual uint32_t GetNeededSpsNum() = 0;
|
||||
virtual uint32_t GetNeededSubsetSpsNum() = 0;
|
||||
virtual uint32_t GetNeededPpsNum() = 0;
|
||||
|
||||
virtual void LoadPrevious (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray,
|
||||
SWelsPPS* pPpsArray) = 0;
|
||||
|
||||
virtual void Update (const uint32_t kuiId, const int iParasetType) = 0;
|
||||
virtual void UpdatePpsList (sWelsEncCtx* pCtx) = 0;
|
||||
|
||||
virtual bool CheckParamCompatibility (SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) = 0;
|
||||
|
||||
virtual uint32_t GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount,
|
||||
uint32_t kuiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) = 0;
|
||||
|
||||
virtual uint32_t InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
|
||||
SWelsSPS* pSps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag) = 0;
|
||||
|
||||
virtual void SetUseSubsetFlag (const uint32_t iPpsId, const bool bUseSubsetSps) = 0;
|
||||
|
||||
virtual void UpdateParaSetNum (sWelsEncCtx* pCtx) = 0;
|
||||
|
||||
virtual int32_t GetCurrentPpsId (const int32_t iPpsId, const int32_t iIdrLoop) = 0;
|
||||
|
||||
virtual void OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList,
|
||||
sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) = 0;
|
||||
virtual void LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList) = 0;
|
||||
|
||||
virtual int32_t GetSpsIdx (const int32_t iIdx) = 0;
|
||||
};
|
||||
|
||||
|
||||
class CWelsParametersetIdConstant : public IWelsParametersetStrategy {
|
||||
public:
|
||||
|
||||
CWelsParametersetIdConstant (const bool bSimulcastAVC, const int32_t kiSpatialLayerNum);
|
||||
virtual ~ CWelsParametersetIdConstant();
|
||||
|
||||
virtual int32_t GetPpsIdOffset (const int32_t iPpsId);
|
||||
virtual int32_t GetSpsIdOffset (const int32_t iPpsId, const int32_t iSpsId);
|
||||
int32_t* GetSpsIdOffsetList (const int iParasetType);
|
||||
|
||||
uint32_t GetAllNeededParasetNum();
|
||||
|
||||
virtual uint32_t GetNeededSpsNum();
|
||||
virtual uint32_t GetNeededSubsetSpsNum();
|
||||
virtual uint32_t GetNeededPpsNum();
|
||||
|
||||
virtual void LoadPrevious (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray,
|
||||
SWelsPPS* pPpsArray);
|
||||
|
||||
virtual void Update (const uint32_t kuiId, const int iParasetType);
|
||||
virtual void UpdatePpsList (sWelsEncCtx* pCtx) {};
|
||||
|
||||
bool CheckParamCompatibility (SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) {
|
||||
return true;
|
||||
};
|
||||
|
||||
virtual uint32_t GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, uint32_t kuiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer);
|
||||
|
||||
virtual uint32_t InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
|
||||
SWelsSPS* pSps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag);
|
||||
|
||||
virtual void SetUseSubsetFlag (const uint32_t iPpsId, const bool bUseSubsetSps);
|
||||
|
||||
virtual void UpdateParaSetNum (sWelsEncCtx* pCtx) {};
|
||||
|
||||
virtual int32_t GetCurrentPpsId (const int32_t iPpsId, const int32_t iIdrLoop) {
|
||||
return iPpsId;
|
||||
};
|
||||
|
||||
virtual void OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList,
|
||||
sWelsEncCtx* pCtx,
|
||||
SExistingParasetList* pExistingParasetList) {};
|
||||
virtual void LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList) {};
|
||||
|
||||
virtual int32_t GetSpsIdx (const int32_t iIdx) {
|
||||
return 0;
|
||||
};
|
||||
protected:
|
||||
|
||||
virtual void LoadPreviousSps (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray) {};
|
||||
virtual void LoadPreviousPps (SExistingParasetList* pExistingParasetList, SWelsPPS* pPpsArray) {};
|
||||
|
||||
protected:
|
||||
SParaSetOffset m_sParaSetOffset;
|
||||
bool m_bSimulcastAVC;
|
||||
int32_t m_iSpatialLayerNum;
|
||||
|
||||
uint32_t m_iBasicNeededSpsNum;
|
||||
uint32_t m_iBasicNeededPpsNum;
|
||||
};
|
||||
|
||||
/*
|
||||
typedef struct TagParaSetOffsetVariable {
|
||||
int32_t iParaSetIdDelta[MAX_DQ_LAYER_NUM+1];//mark delta between SPS_ID_in_bs and sps_id_in_encoder, can be minus, for each dq-layer
|
||||
//need not extra +1 due no MGS and FMO case so far
|
||||
bool bUsedParaSetIdInBs[MAX_PPS_COUNT]; //mark the used SPS_ID with 1
|
||||
uint32_t uiNextParaSetIdToUseInBs; //mark the next SPS_ID_in_bs, for all layers
|
||||
} SParaSetOffsetVariable;
|
||||
|
||||
typedef struct TagParaSetOffset {
|
||||
//in PS0 design, "sParaSetOffsetVariable" record the previous paras before current IDR, AND NEED to be stacked and recover across IDR
|
||||
SParaSetOffsetVariable
|
||||
sParaSetOffsetVariable[PARA_SET_TYPE]; //PARA_SET_TYPE=3; paraset_type = 0: AVC_SPS; =1: Subset_SPS; =2: PPS
|
||||
//in PSO design, "bPpsIdMappingIntoSubsetsps" uses the current para of current IDR period
|
||||
bool
|
||||
bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM+1]; // need not extra +1 due no MGS and FMO case so far
|
||||
|
||||
int32_t iPpsIdList[MAX_DQ_LAYER_NUM][MAX_PPS_COUNT]; //index0: max pps types; index1: for differnt IDRs, if only index0=1, index1 can reach MAX_PPS_COUNT
|
||||
|
||||
//#if _DEBUG
|
||||
int32_t eSpsPpsIdStrategy;
|
||||
//#endif
|
||||
|
||||
uint32_t uiNeededSpsNum;
|
||||
uint32_t uiNeededSubsetSpsNum;
|
||||
uint32_t uiNeededPpsNum;
|
||||
|
||||
uint32_t uiInUseSpsNum;
|
||||
uint32_t uiInUseSubsetSpsNum;
|
||||
uint32_t uiInUsePpsNum;
|
||||
} SParaSetOffset;
|
||||
*/
|
||||
|
||||
class CWelsParametersetIdNonConstant : public CWelsParametersetIdConstant {
|
||||
public:
|
||||
CWelsParametersetIdNonConstant (const bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum): CWelsParametersetIdConstant (bSimulcastAVC, kiSpatialLayerNum) {};
|
||||
|
||||
virtual void OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList,
|
||||
sWelsEncCtx* pCtx,
|
||||
SExistingParasetList* pExistingParasetList);
|
||||
virtual void LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList);
|
||||
};
|
||||
|
||||
class CWelsParametersetIdIncreasing : public CWelsParametersetIdNonConstant {
|
||||
public:
|
||||
CWelsParametersetIdIncreasing (const bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum): CWelsParametersetIdNonConstant (bSimulcastAVC, kiSpatialLayerNum) {};
|
||||
|
||||
|
||||
virtual int32_t GetPpsIdOffset (const int32_t iPpsId);
|
||||
virtual int32_t GetSpsIdOffset (const int32_t iPpsId, const int32_t iSpsId);
|
||||
|
||||
virtual void Update (const uint32_t kuiId, const int iParasetType);
|
||||
|
||||
protected:
|
||||
|
||||
//void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable, const int32_t kiCurEncoderParaSetId,
|
||||
// const uint32_t kuiMaxIdInBs);
|
||||
|
||||
private:
|
||||
void DebugPps (const int32_t kiPpsId);
|
||||
void DebugSpsPps (const int32_t iPpsId, const int32_t iSpsId);
|
||||
};
|
||||
|
||||
|
||||
class CWelsParametersetSpsListing : public CWelsParametersetIdNonConstant {
|
||||
public:
|
||||
CWelsParametersetSpsListing (const bool bSimulcastAVC, const int32_t kiSpatialLayerNum);
|
||||
|
||||
virtual uint32_t GetNeededSubsetSpsNum();
|
||||
|
||||
virtual void LoadPrevious (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray,
|
||||
SWelsPPS* pPpsArray);
|
||||
|
||||
bool CheckParamCompatibility (SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx);
|
||||
|
||||
virtual uint32_t GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, uint32_t kuiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer);
|
||||
|
||||
virtual void UpdateParaSetNum (sWelsEncCtx* pCtx);
|
||||
|
||||
int32_t GetSpsIdx (const int32_t iIdx) {
|
||||
return iIdx;
|
||||
};
|
||||
|
||||
virtual void OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList,
|
||||
sWelsEncCtx* pCtx,
|
||||
SExistingParasetList* pExistingParasetList);
|
||||
protected:
|
||||
virtual void LoadPreviousSps (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray);
|
||||
virtual bool CheckPpsGenerating();
|
||||
virtual int32_t SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps);
|
||||
};
|
||||
|
||||
class CWelsParametersetSpsPpsListing : public CWelsParametersetSpsListing {
|
||||
public:
|
||||
CWelsParametersetSpsPpsListing (const bool bSimulcastAVC, const int32_t kiSpatialLayerNum);
|
||||
|
||||
//uint32_t GetNeededPpsNum();
|
||||
|
||||
virtual void UpdatePpsList (sWelsEncCtx* pCtx);
|
||||
|
||||
virtual uint32_t InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
|
||||
SWelsSPS* pSps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag);
|
||||
|
||||
virtual void UpdateParaSetNum (sWelsEncCtx* pCtx);
|
||||
|
||||
virtual int32_t GetCurrentPpsId (const int32_t iPpsId, const int32_t iIdrLoop);
|
||||
|
||||
virtual void OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList,
|
||||
sWelsEncCtx* pCtx,
|
||||
SExistingParasetList* pExistingParasetList);
|
||||
virtual void LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable, int32_t* pPpsIdList);
|
||||
protected:
|
||||
virtual void LoadPreviousPps (SExistingParasetList* pExistingParasetList, SWelsPPS* pPpsArray);
|
||||
|
||||
virtual bool CheckPpsGenerating();
|
||||
virtual int32_t SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps);
|
||||
};
|
||||
|
||||
class CWelsParametersetSpsListingPpsIncreasing : public CWelsParametersetSpsListing {
|
||||
public:
|
||||
CWelsParametersetSpsListingPpsIncreasing (const bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum): CWelsParametersetSpsListing (bSimulcastAVC, kiSpatialLayerNum) {};
|
||||
|
||||
virtual int32_t GetPpsIdOffset (const int32_t kiPpsId);
|
||||
virtual void Update (const uint32_t kuiId, const int iParasetType);
|
||||
};
|
||||
|
||||
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||
SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray, bool bSVCBaseLayer);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -193,6 +193,8 @@ typedef int32_t (*PWelsSpatialWriteMbSyn) (sWelsEncCtx* pCtx, SSlice* pSlice, SM
|
||||
typedef void (*PStashMBStatus) (SDynamicSlicingStack* pDss, SSlice* pSlice, int32_t iMbSkipRun);
|
||||
typedef int32_t (*PStashPopMBStatus) (SDynamicSlicingStack* pDss, SSlice* pSlice);
|
||||
|
||||
class IWelsParametersetStrategy;
|
||||
|
||||
struct TagWelsFuncPointerList {
|
||||
SExpandPicFunc sExpandPicFunc;
|
||||
PFillInterNeighborCacheFunc pfFillInterNeighborCache;
|
||||
@ -288,6 +290,8 @@ struct TagWelsFuncPointerList {
|
||||
PWelsSpatialWriteMbSyn pfWelsSpatialWriteMbSyn;
|
||||
PStashMBStatus pfStashMBStatus;
|
||||
PStashPopMBStatus pfStashPopMBStatus;
|
||||
|
||||
IWelsParametersetStrategy* pParametersetStrategy;
|
||||
};
|
||||
|
||||
} //end of namespace WelsEnc {
|
||||
|
@ -380,29 +380,12 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr
|
||||
* \note Call it in case EWelsNalUnitType is PPS.
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* pPSOVector) {
|
||||
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux,
|
||||
IWelsParametersetStrategy* pParametersetStrategy) {
|
||||
SBitStringAux* pLocalBitStringAux = pBitStringAux;
|
||||
|
||||
const int32_t kiParameterSetType = (pPSOVector != NULL) ? (pPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId] ?
|
||||
PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) : 0;
|
||||
|
||||
BsWriteUE (pLocalBitStringAux, pPps->iPpsId
|
||||
+ ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]) : 0));
|
||||
BsWriteUE (pLocalBitStringAux, pPps->iSpsId
|
||||
+ ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]) : 0));
|
||||
|
||||
#if _DEBUG
|
||||
//SParaSetOffset use, 110421
|
||||
if ((pPSOVector != NULL) && (INCREASING_ID & pPSOVector->eSpsPpsIdStrategy)) {
|
||||
const int32_t kiTmpSpsIdInBs = pPps->iSpsId +
|
||||
pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId];
|
||||
const int32_t tmp_pps_id_in_bs = pPps->iPpsId +
|
||||
pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId];
|
||||
assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
|
||||
assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
|
||||
assert (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
|
||||
}
|
||||
#endif
|
||||
BsWriteUE (pLocalBitStringAux, pPps->iPpsId + pParametersetStrategy->GetPpsIdOffset (pPps->iPpsId));
|
||||
BsWriteUE (pLocalBitStringAux, pPps->iSpsId + pParametersetStrategy->GetSpsIdOffset (pPps->iPpsId, pPps->iSpsId));
|
||||
|
||||
BsWriteOneBit (pLocalBitStringAux, pPps->bEntropyCodingModeFlag);
|
||||
BsWriteOneBit (pLocalBitStringAux, false/*pPps->bPicOrderPresentFlag*/);
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "deblocking.h"
|
||||
#include "ref_list_mgr_svc.h"
|
||||
#include "mc.h"
|
||||
#include "paraset_strategy.h"
|
||||
#include "sample.h"
|
||||
|
||||
#include "svc_enc_golomb.h"
|
||||
@ -221,6 +222,10 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
|
||||
|
||||
InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
|
||||
|
||||
pFuncList->pParametersetStrategy = IWelsParametersetStrategy::CreateParametersetStrategy (pParam->eSpsPpsIdStrategy,
|
||||
pParam->bSimulcastAVC, pParam->iSpatialLayerNum);
|
||||
WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, (NULL == pFuncList->pParametersetStrategy))
|
||||
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
|
@ -767,12 +767,15 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara
|
||||
++ iDIndex;
|
||||
} while (iDIndex < iNumDependencyLayers);
|
||||
|
||||
if (NULL == (*ppCtx)->pFuncList || NULL == (*ppCtx)->pFuncList->pParametersetStrategy) {
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||
"AcquireLayersNals(), pFuncList and pParametersetStrategy needed to be initialized first!");
|
||||
return 1;
|
||||
}
|
||||
// count parasets
|
||||
iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +
|
||||
iCountNumLayers // plus iCountNumLayers for reserved application
|
||||
+ (*ppCtx)->GetNeededSpsNum()
|
||||
+ (*ppCtx)->GetNeededSubsetSpsNum()
|
||||
+ (*ppCtx)->GetNeededPpsNum();
|
||||
+ (*ppCtx)->pFuncList->pParametersetStrategy->GetAllNeededParasetNum();
|
||||
|
||||
// to check number of layers / nals / slices dependencies, 12/8/2010
|
||||
if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
|
||||
@ -956,152 +959,7 @@ void FreeRefList (SRefList*& pRefList, CMemoryAlign* pMa, const int iMaxNumRefF
|
||||
pRefList = NULL;
|
||||
}
|
||||
|
||||
static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t kiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) {
|
||||
int32_t iRet = 0;
|
||||
|
||||
if (!kbUseSubsetSps) {
|
||||
pSps = & (pCtx->pSpsArray[kiSpsId]);
|
||||
} else {
|
||||
pSubsetSps = & (pCtx->pSubsetArray[kiSpsId]);
|
||||
pSps = &pSubsetSps->pSps;
|
||||
}
|
||||
|
||||
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
// Need port pSps/pPps initialization due to spatial scalability changed
|
||||
if (!kbUseSubsetSps) {
|
||||
iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
|
||||
bSVCBaselayer);
|
||||
} else {
|
||||
iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) {
|
||||
|
||||
if ((pSps1->iMbWidth != pSps2->iMbWidth)
|
||||
|| (pSps1->iMbHeight != pSps2->iMbHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum)
|
||||
|| (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag)
|
||||
|| (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft)
|
||||
|| (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight)
|
||||
|| (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop)
|
||||
|| (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc)
|
||||
|| (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag)
|
||||
|| (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag)
|
||||
|| (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag)
|
||||
|| (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag)
|
||||
|| (pSps1->iLevelIdc != pSps2->iLevelIdc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) {
|
||||
if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||
SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray, bool bSVCBaseLayer) {
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
|
||||
assert (iSpsNumInUse <= MAX_SPS_COUNT);
|
||||
if (!kbUseSubsetSps) {
|
||||
SWelsSPS sTmpSps;
|
||||
WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
|
||||
bSVCBaseLayer);
|
||||
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||
if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SSubsetSps sTmpSubsetSps;
|
||||
WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||
|
||||
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||
if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId,
|
||||
const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse,
|
||||
SWelsPPS* pPpsArray) {
|
||||
#if !defined(DISABLE_FMO_FEATURE)
|
||||
// feature not supported yet
|
||||
return INVALID_ID;
|
||||
#endif//!DISABLE_FMO_FEATURE
|
||||
|
||||
SWelsPPS sTmpPps;
|
||||
WelsInitPps (&sTmpPps,
|
||||
pSps,
|
||||
pSubsetSps,
|
||||
0,
|
||||
true,
|
||||
kbUseSubsetSps,
|
||||
kbEntropyCodingFlag);
|
||||
|
||||
assert (iPpsNumInUse <= MAX_PPS_COUNT);
|
||||
for (int32_t iId = 0; iId < iPpsNumInUse; iId++) {
|
||||
if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId)
|
||||
&& (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag)
|
||||
&& (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp)
|
||||
&& (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs)
|
||||
&& (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset)
|
||||
&& (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag)
|
||||
) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
static inline int32_t InitSliceList (sWelsEncCtx** ppCtx,
|
||||
SDqLayer* pDqLayer,
|
||||
@ -1248,7 +1106,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
CMemoryAlign* pMa = NULL;
|
||||
int32_t iDlayerCount = 0;
|
||||
int32_t iDlayerIndex = 0;
|
||||
uint32_t iSpsId = 0;
|
||||
int32_t iSpsId = 0;
|
||||
uint32_t iPpsId = 0;
|
||||
uint32_t iNumRef = 0;
|
||||
int32_t iResult = 0;
|
||||
@ -1388,8 +1246,10 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
}
|
||||
|
||||
// for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010
|
||||
const int32_t kiNeededSpsNum = (*ppCtx)->GetNeededSpsNum();
|
||||
const int32_t kiNeededSubsetSpsNum = (*ppCtx)->GetNeededSubsetSpsNum();
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pFuncList), FreeMemorySvc (ppCtx))
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pFuncList->pParametersetStrategy), FreeMemorySvc (ppCtx))
|
||||
const int32_t kiNeededSpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSpsNum();
|
||||
const int32_t kiNeededSubsetSpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSubsetSpsNum();
|
||||
(*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMallocz (kiNeededSpsNum * sizeof (SWelsSPS), "pSpsArray");
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
|
||||
if (kiNeededSubsetSpsNum > 0) {
|
||||
@ -1399,36 +1259,15 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
(*ppCtx)->pSubsetArray = NULL;
|
||||
}
|
||||
|
||||
if ((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
|
||||
(*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
|
||||
memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
|
||||
if (kiNeededSubsetSpsNum > 0) {
|
||||
(*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
|
||||
memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
} else {
|
||||
(*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// PPS
|
||||
const int32_t kiNeededPpsNum = (*ppCtx)->GetNeededPpsNum();
|
||||
const int32_t kiNeededPpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededPpsNum();
|
||||
(*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMallocz (kiNeededPpsNum * sizeof (SWelsPPS), "pPPSArray");
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
|
||||
|
||||
// copy from existing if the pointer exists
|
||||
if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
|
||||
(*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
|
||||
memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||
}
|
||||
(*ppCtx)->pFuncList->pParametersetStrategy->LoadPrevious (pExistingParasetList, (*ppCtx)->pSpsArray,
|
||||
(*ppCtx)->pSubsetArray, (*ppCtx)->pPPSArray);
|
||||
|
||||
|
||||
if (INCREASING_ID & pParam->eSpsPpsIdStrategy) {
|
||||
(*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector);
|
||||
} else {
|
||||
(*ppCtx)->pPSOVector = NULL;
|
||||
}
|
||||
|
||||
(*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap");
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pDqIdcMap), FreeMemorySvc (ppCtx))
|
||||
|
||||
@ -1441,79 +1280,18 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
&& (iDlayerIndex == BASE_DEPENDENCY_ID);
|
||||
pDqIdc->uiSpatialId = iDlayerIndex;
|
||||
|
||||
if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) {
|
||||
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer);
|
||||
iSpsId = (*ppCtx)->pFuncList->pParametersetStrategy->GenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer);
|
||||
WELS_VERIFY_RETURN_IF (ENC_RETURN_UNSUPPORTED_PARA, (0 > iSpsId))
|
||||
if (!bUseSubsetSps) {
|
||||
pSps = & ((*ppCtx)->pSpsArray[iSpsId]);
|
||||
} else {
|
||||
//SPS_LISTING_AND_PPS_INCREASING == pParam->eSpsPpsIdStrategy
|
||||
//check if the current param can fit in an existing SPS
|
||||
const int32_t kiFoundSpsId = FindExistingSps ((*ppCtx)->pSvcParam, bUseSubsetSps, iDlayerIndex, iDlayerCount,
|
||||
bUseSubsetSps ? ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum) : ((*ppCtx)->sPSOVector.uiInUseSpsNum),
|
||||
(*ppCtx)->pSpsArray,
|
||||
(*ppCtx)->pSubsetArray, bSvcBaselayer);
|
||||
|
||||
|
||||
if (INVALID_ID != kiFoundSpsId) {
|
||||
//if yes, set pSps or pSubsetSps to it
|
||||
iSpsId = kiFoundSpsId;
|
||||
if (!bUseSubsetSps) {
|
||||
pSps = & ((*ppCtx)->pSpsArray[kiFoundSpsId]);
|
||||
} else {
|
||||
pSubsetSps = & ((*ppCtx)->pSubsetArray[kiFoundSpsId]);
|
||||
}
|
||||
} else {
|
||||
//if no, generate a new SPS as usual
|
||||
if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (MAX_PPS_COUNT <= (*ppCtx)->sPSOVector.uiInUsePpsNum)) {
|
||||
//check if we can generate new SPS or not
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
|
||||
iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++);
|
||||
if (iSpsId >= MAX_SPS_COUNT) {
|
||||
if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) {
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
// reset current list
|
||||
if (!bUseSubsetSps) {
|
||||
(*ppCtx)->sPSOVector.uiInUseSpsNum = 1;
|
||||
memset ((*ppCtx)->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
} else {
|
||||
(*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 1;
|
||||
memset ((*ppCtx)->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
}
|
||||
iSpsId = 0;
|
||||
}
|
||||
|
||||
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer);
|
||||
}
|
||||
pSubsetSps = & ((*ppCtx)->pSubsetArray[iSpsId]);
|
||||
}
|
||||
|
||||
if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) {
|
||||
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
||||
// initialize pPps
|
||||
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||
} else {
|
||||
const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, bUseSubsetSps, iSpsId,
|
||||
pParam->iEntropyCodingModeFlag != 0,
|
||||
(*ppCtx)->sPSOVector.uiInUsePpsNum,
|
||||
(*ppCtx)->pPPSArray);
|
||||
|
||||
|
||||
if (INVALID_ID != kiFoundPpsId) {
|
||||
//if yes, set pPps to it
|
||||
iPpsId = kiFoundPpsId;
|
||||
pPps = & ((*ppCtx)->pPPSArray[kiFoundPpsId]);
|
||||
} else {
|
||||
iPpsId = ((*ppCtx)->sPSOVector.uiInUsePpsNum++);
|
||||
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
||||
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||
}
|
||||
}
|
||||
iPpsId = (*ppCtx)->pFuncList->pParametersetStrategy->InitPps ((*ppCtx), iSpsId, pSps, pSubsetSps, iPpsId, true,
|
||||
bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||
pPps = & ((*ppCtx)->pPPSArray[iPpsId]);
|
||||
|
||||
// Not using FMO in SVC coding so far, come back if need FMO
|
||||
{
|
||||
@ -1533,8 +1311,6 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
pDqIdc->iSpsId = iSpsId;
|
||||
pDqIdc->iPpsId = iPpsId;
|
||||
|
||||
(*ppCtx)->sPSOVector.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps;
|
||||
|
||||
if ((pParam->bSimulcastAVC) || (bUseSubsetSps))
|
||||
++ iSpsId;
|
||||
++ iPpsId;
|
||||
@ -1547,13 +1323,8 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
|
||||
++ iDlayerIndex;
|
||||
}
|
||||
if (SPS_LISTING & pParam->eSpsPpsIdStrategy) {
|
||||
(*ppCtx)->iSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||
(*ppCtx)->iSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||
}
|
||||
if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) {
|
||||
(*ppCtx)->iPpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
|
||||
}
|
||||
|
||||
(*ppCtx)->pFuncList->pParametersetStrategy->UpdateParaSetNum ((*ppCtx));
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1908,8 +1679,8 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingPa
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int32_t kiSpsSize = (*ppCtx)->GetNeededSpsNum() * SPS_BUFFER_SIZE;
|
||||
const int32_t kiPpsSize = (*ppCtx)->GetNeededPpsNum() * PPS_BUFFER_SIZE;
|
||||
const int32_t kiSpsSize = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSpsNum() * SPS_BUFFER_SIZE;
|
||||
const int32_t kiPpsSize = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededPpsNum() * PPS_BUFFER_SIZE;
|
||||
iNonVclLayersBsSizeCount = SSEI_BUFFER_SIZE + kiSpsSize + kiPpsSize;
|
||||
|
||||
bool bDynamicSlice = false;
|
||||
@ -2316,6 +2087,10 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
|
||||
FreeCodingParam (&pCtx->pSvcParam, pMa);
|
||||
if (NULL != pCtx->pFuncList) {
|
||||
if (NULL != pCtx->pFuncList->pParametersetStrategy) {
|
||||
WELS_DELETE_OP (pCtx->pFuncList->pParametersetStrategy);
|
||||
}
|
||||
|
||||
pMa->WelsFree (pCtx->pFuncList, "SWelsFuncPtrList");
|
||||
pCtx->pFuncList = NULL;
|
||||
}
|
||||
@ -2867,9 +2642,8 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
|
||||
int32_t iCurPpsId = pDqIdc->iPpsId;
|
||||
int32_t iCurSpsId = pDqIdc->iSpsId;
|
||||
|
||||
if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) {
|
||||
iCurPpsId = pCtx->sPSOVector.iPpsIdList[pDqIdc->iPpsId][WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT];
|
||||
}
|
||||
iCurPpsId = pCtx->pFuncList->pParametersetStrategy->GetCurrentPpsId (iCurPpsId,
|
||||
WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT);
|
||||
|
||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId;
|
||||
pCurDq->sLayerInfo.pPpsP =
|
||||
@ -3148,45 +2922,12 @@ static inline void PrefetchReferencePicture (sWelsEncCtx* pCtx, const EVideoFram
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable, const int32_t kiCurEncoderParaSetId,
|
||||
const uint32_t kuiMaxIdInBs) { //paraset_type = 0: SPS; =1: PPS
|
||||
//SPS_ID in avc_sps and pSubsetSps will be different using this
|
||||
//SPS_ID case example:
|
||||
//1st enter: next_spsid_in_bs == 0; spsid == 0; delta==0; //actual spsid_in_bs == 0
|
||||
//1st finish: next_spsid_in_bs == 1;
|
||||
//2nd enter: next_spsid_in_bs == 1; spsid == 0; delta==1; //actual spsid_in_bs == 1
|
||||
//2nd finish: next_spsid_in_bs == 2;
|
||||
//31st enter: next_spsid_in_bs == 31; spsid == 0~2; delta==31~29; //actual spsid_in_bs == 31
|
||||
//31st finish:next_spsid_in_bs == 0;
|
||||
//31st enter: next_spsid_in_bs == 0; spsid == 0~2; delta==-2~0; //actual spsid_in_bs == 0
|
||||
//31st finish:next_spsid_in_bs == 1;
|
||||
|
||||
const int32_t kiEncId = kiCurEncoderParaSetId;
|
||||
uint32_t uiNextIdInBs = sParaSetOffsetVariable->uiNextParaSetIdToUseInBs;
|
||||
|
||||
//update current layer's pCodingParam
|
||||
sParaSetOffsetVariable->iParaSetIdDelta[kiEncId] = uiNextIdInBs -
|
||||
kiEncId; //for current parameter set, change its id_delta
|
||||
//write pso pData for next update:
|
||||
sParaSetOffsetVariable->bUsedParaSetIdInBs[uiNextIdInBs] = true; // update current used_id
|
||||
|
||||
//prepare for next update:
|
||||
// find the next avaibable iId
|
||||
++uiNextIdInBs;
|
||||
if (uiNextIdInBs >= kuiMaxIdInBs) {
|
||||
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
|
||||
}
|
||||
// update next_id
|
||||
sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
|
||||
}
|
||||
|
||||
int32_t WelsWriteOneSPS (sWelsEncCtx* pCtx, const int32_t kiSpsIdx, int32_t& iNalSize) {
|
||||
int iNal = pCtx->pOut->iNalIndex;
|
||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST);
|
||||
|
||||
WelsWriteSpsNal (&pCtx->pSpsArray[kiSpsIdx], &pCtx->pOut->sBsWrite,
|
||||
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0]));
|
||||
pCtx->pFuncList->pParametersetStrategy->GetSpsIdOffsetList (PARA_SET_TYPE_AVCSPS));
|
||||
WelsUnloadNal (pCtx->pOut);
|
||||
|
||||
int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||
@ -3204,8 +2945,9 @@ int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNa
|
||||
int32_t iNal = pCtx->pOut->iNalIndex;
|
||||
/* generate picture parameter set */
|
||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST);
|
||||
|
||||
WelsWritePpsSyntax (&pCtx->pPPSArray[kiPpsIdx], &pCtx->pOut->sBsWrite,
|
||||
((SPS_PPS_LISTING != pCtx->pSvcParam->eSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL);
|
||||
pCtx->pFuncList->pParametersetStrategy);
|
||||
WelsUnloadNal (pCtx->pOut);
|
||||
|
||||
int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||
@ -3218,43 +2960,6 @@ int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNa
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
void UpdatePpsList (sWelsEncCtx* pCtx) {
|
||||
assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
|
||||
|
||||
//Generate PPS LIST
|
||||
int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
|
||||
|
||||
for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
|
||||
for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
|
||||
pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
|
||||
memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
|
||||
pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
|
||||
pCtx->iPpsNum++;
|
||||
}
|
||||
|
||||
assert (pCtx->iPpsNum == MAX_PPS_COUNT);
|
||||
pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum;
|
||||
|
||||
}
|
||||
|
||||
void UpdateSpsPpsIdStrategyWithIncreasingId (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) {
|
||||
#if _DEBUG
|
||||
pPSOVector->eSpsPpsIdStrategy = INCREASING_ID;
|
||||
assert (kuiId < MAX_DQ_LAYER_NUM);
|
||||
#endif
|
||||
|
||||
ParasetIdAdditionIdAdjust (& (pPSOVector->sParaSetOffsetVariable[iParasetType]),
|
||||
kuiId,
|
||||
(iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
|
||||
}
|
||||
|
||||
void UpdateSpsPpsIdStrategyWithConstantId (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) {
|
||||
memset (pPSOVector, 0, sizeof (SParaSetOffset));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief write all parameter sets introduced in SVC extension
|
||||
@ -3269,22 +2974,16 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
int32_t iNalLength = 0;
|
||||
int32_t iReturn = ENC_RETURN_SUCCESS;
|
||||
|
||||
if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal)
|
||||
if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal || NULL == pCtx->pFuncList->pParametersetStrategy)
|
||||
return ENC_RETURN_UNEXPECTED;
|
||||
|
||||
*pTotalLength = 0;
|
||||
/* write all SPS */
|
||||
iIdx = 0;
|
||||
while (iIdx < pCtx->iSpsNum) {
|
||||
// TODO (Sijia) wrap different operation of eSpsPpsIdStrategy to classes to hide the details
|
||||
if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
} else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
}
|
||||
|
||||
pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
/* generate sequence parameters set */
|
||||
iId = (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy) ? iIdx : 0;
|
||||
iId = pCtx->pFuncList->pParametersetStrategy->GetSpsIdx (iIdx);
|
||||
|
||||
WelsWriteOneSPS (pCtx, iId, iNalLength);
|
||||
|
||||
@ -3300,11 +2999,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
while (iIdx < pCtx->iSubsetSpsNum) {
|
||||
iNal = pCtx->pOut->iNalIndex;
|
||||
|
||||
if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSubsetArray[iIdx].pSps.uiSpsId,
|
||||
PARA_SET_TYPE_SUBSETSPS);
|
||||
}
|
||||
|
||||
pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSubsetArray[iIdx].pSps.uiSpsId, PARA_SET_TYPE_SUBSETSPS);
|
||||
|
||||
iId = iIdx;
|
||||
|
||||
@ -3312,7 +3007,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST);
|
||||
|
||||
WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite,
|
||||
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0]));
|
||||
pCtx->pFuncList->pParametersetStrategy->GetSpsIdOffsetList (PARA_SET_TYPE_SUBSETSPS));
|
||||
WelsUnloadNal (pCtx->pOut);
|
||||
|
||||
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||
@ -3329,16 +3024,11 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
++ iCountNal;
|
||||
}
|
||||
|
||||
/* write all PPS */
|
||||
if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
|
||||
UpdatePpsList (pCtx);
|
||||
}
|
||||
pCtx->pFuncList->pParametersetStrategy->UpdatePpsList (pCtx);
|
||||
|
||||
iIdx = 0;
|
||||
while (iIdx < pCtx->iPpsNum) {
|
||||
if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
|
||||
UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
|
||||
}
|
||||
pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
|
||||
|
||||
WelsWriteOnePPS (pCtx, iIdx, iNalLength);
|
||||
|
||||
@ -3552,10 +3242,9 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx,
|
||||
int32_t iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
|
||||
if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
} else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
|
||||
if (pCtx->pFuncList->pParametersetStrategy) {
|
||||
pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
|
||||
}
|
||||
|
||||
iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
|
||||
@ -3589,10 +3278,8 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx,
|
||||
iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
|
||||
if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
|
||||
} else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
|
||||
UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
|
||||
if (pCtx->pFuncList->pParametersetStrategy) {
|
||||
pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
|
||||
}
|
||||
|
||||
iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
|
||||
@ -3666,9 +3353,7 @@ int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
|
||||
}
|
||||
|
||||
// write PPS
|
||||
if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
|
||||
UpdatePpsList (pCtx);
|
||||
}
|
||||
pCtx->pFuncList->pParametersetStrategy->UpdatePpsList (pCtx);
|
||||
|
||||
//TODO: under new strategy, will PPS be correctly updated?
|
||||
for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) {
|
||||
@ -3811,22 +3496,29 @@ EVideoFrameType PrepareEncodeFrame (sWelsEncCtx* pCtx, SLayerBSInfo*& pLayerBsIn
|
||||
pCtx->iContinualSkipFrames = 0;
|
||||
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iCurDid], pParamInternal->iCodingIndex,
|
||||
pSvcParam->uiGopSize);
|
||||
pCtx->uiTemporalId = iCurTid;
|
||||
if (eFrameType == videoFrameTypeIDR) {
|
||||
// write parameter sets bitstream or SEI/SSEI (if any) here
|
||||
// TODO: use function pointer instead
|
||||
if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
|
||||
if (pSvcParam->bSimulcastAVC) {
|
||||
pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
++ pCtx->uiIdrPicId;
|
||||
//skip this spatial layer
|
||||
if (iCurTid == INVALID_TEMPORAL_ID) {
|
||||
pParamInternal->iCodingIndex ++;
|
||||
eFrameType = videoFrameTypeSkip;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeSkip;
|
||||
} else {
|
||||
pCtx->uiTemporalId = iCurTid;
|
||||
if (eFrameType == videoFrameTypeIDR) {
|
||||
// write parameter sets bitstream or SEI/SSEI (if any) here
|
||||
// TODO: use function pointer instead
|
||||
if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
|
||||
if (pSvcParam->bSimulcastAVC) {
|
||||
pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
++ pCtx->uiIdrPicId;
|
||||
} else {
|
||||
pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
++ pCtx->uiIdrPicId;
|
||||
}
|
||||
} else {
|
||||
pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
|
||||
++ pCtx->uiIdrPicId;
|
||||
}
|
||||
} else {
|
||||
pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
|
||||
++ pCtx->uiIdrPicId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3931,12 +3623,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
int32_t iDecompositionStages = pSvcParam->sDependencyLayers[iCurDid].iDecompositionStages;
|
||||
pCtx->pCurDqLayer = pCtx->ppDqLayerList[iCurDid];
|
||||
pCtx->uiDependencyId = iCurDid;
|
||||
//skip this spatial layer
|
||||
if (GetTemporalLevel (pParamInternal, pParamInternal->iCodingIndex, pSvcParam->uiGopSize) == INVALID_TEMPORAL_ID) {
|
||||
++iSpatialIdx;
|
||||
pParamInternal->iCodingIndex ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pSvcParam->bSimulcastAVC) {
|
||||
eFrameType = PrepareEncodeFrame (pCtx, pLayerBsInfo, iSpatialNum , iCurDid, iCurTid, iLayerNum, iFrameSize,
|
||||
pFbi->uiTimeStamp);
|
||||
@ -4659,46 +4346,16 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
SExistingParasetList sExistingParasetList;
|
||||
SExistingParasetList* pExistingParasetList = NULL;
|
||||
|
||||
if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy)) {
|
||||
for (int32_t k = 0; k < PARA_SET_TYPE; k++) {
|
||||
memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
|
||||
}
|
||||
memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
if (((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy))) {
|
||||
(*ppCtx)->pFuncList->pParametersetStrategy->OutputCurrentStructure (sTmpPsoVariable, iTmpPpsIdList, (*ppCtx),
|
||||
&sExistingParasetList);
|
||||
|
||||
if ((SPS_LISTING & iOldSpsPpsIdStrategy)
|
||||
&& (SPS_LISTING & pNewParam->eSpsPpsIdStrategy)) {
|
||||
pExistingParasetList = &sExistingParasetList;
|
||||
sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||
memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
if (NULL != (*ppCtx)->pSubsetArray) {
|
||||
sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||
memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
} else {
|
||||
sExistingParasetList.uiInUseSubsetSpsNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
|
||||
&& (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy)) {
|
||||
pExistingParasetList = &sExistingParasetList;
|
||||
sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||
sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
|
||||
memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||
|
||||
if (NULL != (*ppCtx)->pSubsetArray) {
|
||||
sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||
memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
} else {
|
||||
sExistingParasetList.uiInUseSubsetSpsNum = 0;
|
||||
}
|
||||
|
||||
memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WelsUninitEncoderExt (ppCtx);
|
||||
|
||||
/* Update new parameters */
|
||||
@ -4711,14 +4368,10 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
//for sEncoderStatistics
|
||||
memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics));
|
||||
//load back the needed structure for eSpsPpsIdStrategy
|
||||
if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy)) {
|
||||
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
}
|
||||
|
||||
if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
|
||||
&& (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy)) {
|
||||
memcpy (((*ppCtx)->sPSOVector.iPpsIdList), iTmpPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||
if (((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy))
|
||||
|| ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
|
||||
&& (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy))) {
|
||||
(*ppCtx)->pFuncList->pParametersetStrategy->LoadPreviousStructure (sTmpPsoVariable, iTmpPpsIdList);
|
||||
}
|
||||
} else {
|
||||
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
||||
|
713
codec/encoder/core/src/paraset_strategy.cpp
Normal file
713
codec/encoder/core/src/paraset_strategy.cpp
Normal file
@ -0,0 +1,713 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "au_set.h"
|
||||
#include "encoder_context.h"
|
||||
#include "paraset_strategy.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
IWelsParametersetStrategy* IWelsParametersetStrategy::CreateParametersetStrategy (
|
||||
EParameterSetStrategy eSpsPpsIdStrategy, bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum) {
|
||||
|
||||
IWelsParametersetStrategy* pParametersetStrategy = NULL;
|
||||
switch (eSpsPpsIdStrategy) {
|
||||
case INCREASING_ID:
|
||||
pParametersetStrategy = WELS_NEW_OP (CWelsParametersetIdIncreasing (bSimulcastAVC, kiSpatialLayerNum),
|
||||
CWelsParametersetIdIncreasing);
|
||||
WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
|
||||
break;
|
||||
case SPS_LISTING:
|
||||
pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsListing (bSimulcastAVC, kiSpatialLayerNum),
|
||||
CWelsParametersetSpsListing);
|
||||
WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
|
||||
break;
|
||||
case SPS_LISTING_AND_PPS_INCREASING:
|
||||
pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsListingPpsIncreasing (bSimulcastAVC, kiSpatialLayerNum),
|
||||
CWelsParametersetSpsListingPpsIncreasing);
|
||||
WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
|
||||
break;
|
||||
case SPS_PPS_LISTING:
|
||||
pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsPpsListing (bSimulcastAVC, kiSpatialLayerNum),
|
||||
CWelsParametersetSpsPpsListing);
|
||||
WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
|
||||
break;
|
||||
case CONSTANT_ID:
|
||||
default:
|
||||
pParametersetStrategy = WELS_NEW_OP (CWelsParametersetIdConstant (bSimulcastAVC, kiSpatialLayerNum),
|
||||
CWelsParametersetIdConstant);
|
||||
WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
|
||||
break;
|
||||
}
|
||||
|
||||
return pParametersetStrategy;
|
||||
}
|
||||
|
||||
|
||||
static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t kiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) {
|
||||
int32_t iRet = 0;
|
||||
|
||||
if (!kbUseSubsetSps) {
|
||||
pSps = & (pCtx->pSpsArray[kiSpsId]);
|
||||
} else {
|
||||
pSubsetSps = & (pCtx->pSubsetArray[kiSpsId]);
|
||||
pSps = &pSubsetSps->pSps;
|
||||
}
|
||||
|
||||
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
// Need port pSps/pPps initialization due to spatial scalability changed
|
||||
if (!kbUseSubsetSps) {
|
||||
iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
|
||||
bSVCBaselayer);
|
||||
} else {
|
||||
iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) {
|
||||
|
||||
if ((pSps1->iMbWidth != pSps2->iMbWidth)
|
||||
|| (pSps1->iMbHeight != pSps2->iMbHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum)
|
||||
|| (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag)
|
||||
|| (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft)
|
||||
|| (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight)
|
||||
|| (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop)
|
||||
|| (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc)
|
||||
|| (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag)
|
||||
|| (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag)
|
||||
|| (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag)
|
||||
|| (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag)
|
||||
|| (pSps1->iLevelIdc != pSps2->iLevelIdc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) {
|
||||
if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag)
|
||||
|| (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief check if the current parameter can found a presenting sps
|
||||
* \param pParam the current encoding paramter in SWelsSvcCodingParam
|
||||
* \param kbUseSubsetSps bool
|
||||
* \param iDlayerIndex int, the index of current D layer
|
||||
* \param iDlayerCount int, the number of total D layer
|
||||
* \param pSpsArray array of all the stored SPSs
|
||||
* \param pSubsetArray array of all the stored Subset-SPSs
|
||||
* \return 0 - successful
|
||||
* -1 - cannot find existing SPS for current encoder parameter
|
||||
*/
|
||||
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||
SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray, bool bSVCBaseLayer) {
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
|
||||
assert (iSpsNumInUse <= MAX_SPS_COUNT);
|
||||
if (!kbUseSubsetSps) {
|
||||
SWelsSPS sTmpSps;
|
||||
WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
|
||||
bSVCBaseLayer);
|
||||
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||
if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SSubsetSps sTmpSubsetSps;
|
||||
WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||
|
||||
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||
if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
CWelsParametersetIdConstant::CWelsParametersetIdConstant (const bool bSimulcastAVC, const int32_t kiSpatialLayerNum) {
|
||||
memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
|
||||
|
||||
m_bSimulcastAVC = bSimulcastAVC;
|
||||
m_iSpatialLayerNum = kiSpatialLayerNum;
|
||||
|
||||
m_iBasicNeededSpsNum = 1;
|
||||
m_iBasicNeededPpsNum = (1 + m_iSpatialLayerNum);
|
||||
}
|
||||
|
||||
CWelsParametersetIdConstant::~CWelsParametersetIdConstant() {
|
||||
}
|
||||
|
||||
int32_t CWelsParametersetIdConstant::GetPpsIdOffset (const int32_t iPpsId) {
|
||||
return 0;
|
||||
};
|
||||
int32_t CWelsParametersetIdConstant::GetSpsIdOffset (const int32_t iPpsId, const int32_t iSpsId) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
int32_t* CWelsParametersetIdConstant::GetSpsIdOffsetList (const int iParasetType) {
|
||||
return & (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType].iParaSetIdDelta[0]);
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::GetAllNeededParasetNum() {
|
||||
return (GetNeededSpsNum()
|
||||
+ GetNeededSubsetSpsNum()
|
||||
+ GetNeededPpsNum());
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::GetNeededSpsNum() {
|
||||
if (0 >= m_sParaSetOffset.uiNeededSpsNum) {
|
||||
m_sParaSetOffset.uiNeededSpsNum = m_iBasicNeededSpsNum * ((m_bSimulcastAVC) ? (m_iSpatialLayerNum) : (1));
|
||||
}
|
||||
return m_sParaSetOffset.uiNeededSpsNum;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::GetNeededSubsetSpsNum() {
|
||||
if (0 >= m_sParaSetOffset.uiNeededSubsetSpsNum) {
|
||||
m_sParaSetOffset.uiNeededSubsetSpsNum = (m_bSimulcastAVC ? 0 : (m_iSpatialLayerNum - 1));
|
||||
}
|
||||
return m_sParaSetOffset.uiNeededSubsetSpsNum;
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::GetNeededPpsNum() {
|
||||
if (0 == m_sParaSetOffset.uiNeededPpsNum) {
|
||||
m_sParaSetOffset.uiNeededPpsNum = m_iBasicNeededPpsNum * ((m_bSimulcastAVC) ? (m_iSpatialLayerNum) :
|
||||
(1));
|
||||
}
|
||||
return m_sParaSetOffset.uiNeededPpsNum;
|
||||
}
|
||||
|
||||
void CWelsParametersetIdConstant::LoadPrevious (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray, SWelsPPS* pPpsArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
void CWelsParametersetIdConstant::Update (const uint32_t kuiId, const int iParasetType) {
|
||||
memset (&m_sParaSetOffset, 0, sizeof (SParaSetOffset));
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps,
|
||||
const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, uint32_t kuiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) {
|
||||
WelsGenerateNewSps (pCtx, kbUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, kuiSpsId,
|
||||
pSps, pSubsetSps, bSVCBaselayer);
|
||||
return kuiSpsId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CWelsParametersetIdConstant::InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
|
||||
SWelsSPS* pSps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag) {
|
||||
WelsInitPps (& pCtx->pPPSArray[kuiPpsId], pSps, pSubsetSps, kuiPpsId, true, kbUsingSubsetSps, kbEntropyCodingModeFlag);
|
||||
SetUseSubsetFlag (kuiPpsId, kbUsingSubsetSps);
|
||||
return kuiPpsId;
|
||||
}
|
||||
|
||||
void CWelsParametersetIdConstant::SetUseSubsetFlag (const uint32_t iPpsId, const bool bUseSubsetSps) {
|
||||
m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps;
|
||||
}
|
||||
|
||||
void CWelsParametersetIdNonConstant::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
|
||||
int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
|
||||
for (int32_t k = 0; k < PARA_SET_TYPE; k++) {
|
||||
memset ((m_sParaSetOffset.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
|
||||
}
|
||||
memcpy (pParaSetOffsetVariable, m_sParaSetOffset.sParaSetOffsetVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
}
|
||||
void CWelsParametersetIdNonConstant::LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
|
||||
int32_t* pPpsIdList) {
|
||||
memcpy (m_sParaSetOffset.sParaSetOffsetVariable, pParaSetOffsetVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
}
|
||||
|
||||
//
|
||||
//CWelsParametersetIdIncreasing
|
||||
//
|
||||
|
||||
void CWelsParametersetIdIncreasing::DebugSpsPps (const int32_t kiPpsId, const int32_t kiSpsId) {
|
||||
#if _DEBUG
|
||||
//SParaSetOffset use, 110421
|
||||
//if ( (INCREASING_ID & eSpsPpsIdStrategy)) {
|
||||
const int32_t kiParameterSetType = (m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[kiPpsId] ?
|
||||
PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) ;
|
||||
|
||||
const int32_t kiTmpSpsIdInBs = kiSpsId +
|
||||
m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[kiSpsId];
|
||||
const int32_t tmp_pps_id_in_bs = kiPpsId +
|
||||
m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId];
|
||||
assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
|
||||
assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
|
||||
assert (m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
void CWelsParametersetIdIncreasing::DebugPps (const int32_t kiPpsId) {
|
||||
#if _DEBUG
|
||||
const int32_t kiTmpPpsIdInBs = kiPpsId +
|
||||
m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiPpsId ];
|
||||
assert (MAX_PPS_COUNT > kiTmpPpsIdInBs);
|
||||
|
||||
//when activated need to sure there is avialable PPS
|
||||
assert (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].bUsedParaSetIdInBs[kiTmpPpsIdInBs]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
|
||||
const int32_t kiCurEncoderParaSetId,
|
||||
const uint32_t kuiMaxIdInBs) { //paraset_type = 0: SPS; =1: PPS
|
||||
//SPS_ID in avc_sps and pSubsetSps will be different using this
|
||||
//SPS_ID case example:
|
||||
//1st enter: next_spsid_in_bs == 0; spsid == 0; delta==0; //actual spsid_in_bs == 0
|
||||
//1st finish: next_spsid_in_bs == 1;
|
||||
//2nd enter: next_spsid_in_bs == 1; spsid == 0; delta==1; //actual spsid_in_bs == 1
|
||||
//2nd finish: next_spsid_in_bs == 2;
|
||||
//31st enter: next_spsid_in_bs == 31; spsid == 0~2; delta==31~29; //actual spsid_in_bs == 31
|
||||
//31st finish:next_spsid_in_bs == 0;
|
||||
//31st enter: next_spsid_in_bs == 0; spsid == 0~2; delta==-2~0; //actual spsid_in_bs == 0
|
||||
//31st finish:next_spsid_in_bs == 1;
|
||||
|
||||
const int32_t kiEncId = kiCurEncoderParaSetId;
|
||||
uint32_t uiNextIdInBs = sParaSetOffsetVariable->uiNextParaSetIdToUseInBs;
|
||||
|
||||
//update current layer's pCodingParam
|
||||
sParaSetOffsetVariable->iParaSetIdDelta[kiEncId] = uiNextIdInBs -
|
||||
kiEncId; //for current parameter set, change its id_delta
|
||||
//write pso pData for next update:
|
||||
sParaSetOffsetVariable->bUsedParaSetIdInBs[uiNextIdInBs] = true; // update current used_id
|
||||
|
||||
//prepare for next update:
|
||||
// find the next avaibable iId
|
||||
++uiNextIdInBs;
|
||||
if (uiNextIdInBs >= kuiMaxIdInBs) {
|
||||
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
|
||||
}
|
||||
// update next_id
|
||||
sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
|
||||
}
|
||||
|
||||
void CWelsParametersetIdIncreasing::Update (const uint32_t kuiId, const int iParasetType) {
|
||||
#if _DEBUG
|
||||
m_sParaSetOffset.eSpsPpsIdStrategy = INCREASING_ID;
|
||||
assert (kuiId < MAX_DQ_LAYER_NUM);
|
||||
#endif
|
||||
|
||||
ParasetIdAdditionIdAdjust (& (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType]),
|
||||
kuiId,
|
||||
(iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
|
||||
}
|
||||
//((SPS_PPS_LISTING != pEncCtx->pSvcParam->eSpsPpsIdStrategy) ? (&
|
||||
// (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL)
|
||||
|
||||
int32_t CWelsParametersetIdIncreasing::GetPpsIdOffset (const int32_t kiPpsId) {
|
||||
#if _DEBUG
|
||||
DebugPps (kiPpsId);
|
||||
#endif
|
||||
return (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId]);
|
||||
}
|
||||
|
||||
int32_t CWelsParametersetIdIncreasing::GetSpsIdOffset (const int32_t kiPpsId, const int32_t kiSpsId) {
|
||||
const int32_t kiParameterSetType = (m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[kiPpsId] ?
|
||||
PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS);
|
||||
#if _DEBUG
|
||||
DebugSpsPps (kiPpsId, kiSpsId);
|
||||
#endif
|
||||
return (m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[kiSpsId]);
|
||||
}
|
||||
|
||||
//
|
||||
//CWelsParametersetSpsListing
|
||||
//
|
||||
|
||||
CWelsParametersetSpsListing::CWelsParametersetSpsListing (const bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum) : CWelsParametersetIdNonConstant (bSimulcastAVC, kiSpatialLayerNum) {
|
||||
memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
|
||||
|
||||
m_bSimulcastAVC = bSimulcastAVC;
|
||||
m_iSpatialLayerNum = kiSpatialLayerNum;
|
||||
|
||||
m_iBasicNeededSpsNum = MAX_SPS_COUNT;
|
||||
m_iBasicNeededPpsNum = 1;
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetSpsListing::GetNeededSubsetSpsNum() {
|
||||
if (0 >= m_sParaSetOffset.uiNeededSubsetSpsNum) {
|
||||
// sPSOVector.uiNeededSubsetSpsNum = ((pSvcParam->bSimulcastAVC) ? (0) :((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (pSvcParam->iSpatialLayerNum - 1)));
|
||||
m_sParaSetOffset.uiNeededSubsetSpsNum = ((m_bSimulcastAVC) ? (0) :
|
||||
(MAX_SPS_COUNT));
|
||||
}
|
||||
return m_sParaSetOffset.uiNeededSubsetSpsNum;
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsListing::LoadPreviousSps (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray) {
|
||||
//if ((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
|
||||
m_sParaSetOffset.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
|
||||
memcpy (pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
|
||||
if (GetNeededSubsetSpsNum() > 0) {
|
||||
m_sParaSetOffset.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
|
||||
memcpy (pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
} else {
|
||||
m_sParaSetOffset.uiInUseSubsetSpsNum = 0;
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
void CWelsParametersetSpsListing::LoadPrevious (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
|
||||
SSubsetSps* pSubsetArray, SWelsPPS* pPpsArray) {
|
||||
if (NULL == pExistingParasetList) {
|
||||
return;
|
||||
}
|
||||
LoadPreviousSps (pExistingParasetList, pSpsArray, pSubsetArray);
|
||||
LoadPreviousPps (pExistingParasetList, pPpsArray);
|
||||
}
|
||||
|
||||
bool CWelsParametersetSpsListing::CheckParamCompatibility (SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) {
|
||||
if (pCodingParam->iSpatialLayerNum > 1 && (!pCodingParam->bSimulcastAVC)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple svc SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
|
||||
pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);
|
||||
pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWelsParametersetSpsListing::CheckPpsGenerating() {
|
||||
return true;
|
||||
}
|
||||
int32_t CWelsParametersetSpsListing::SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps) {
|
||||
|
||||
// reset current list
|
||||
if (!kbUseSubsetSps) {
|
||||
m_sParaSetOffset.uiInUseSpsNum = 1;
|
||||
memset (pCtx->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
} else {
|
||||
m_sParaSetOffset.uiInUseSubsetSpsNum = 1;
|
||||
memset (pCtx->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
}
|
||||
|
||||
//iSpsId = 0;
|
||||
return 0;
|
||||
}
|
||||
uint32_t CWelsParametersetSpsListing::GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps,
|
||||
const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, uint32_t kuiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSvcBaselayer) {
|
||||
//check if the current param can fit in an existing SPS
|
||||
const int32_t kiFoundSpsId = FindExistingSps (pCtx->pSvcParam, kbUseSubsetSps, iDlayerIndex, iDlayerCount,
|
||||
kbUseSubsetSps ? (m_sParaSetOffset.uiInUseSubsetSpsNum) : (m_sParaSetOffset.uiInUseSpsNum),
|
||||
pCtx->pSpsArray,
|
||||
pCtx->pSubsetArray, bSvcBaselayer);
|
||||
|
||||
|
||||
if (INVALID_ID != kiFoundSpsId) {
|
||||
//if yes, set pSps or pSubsetSps to it
|
||||
kuiSpsId = kiFoundSpsId;
|
||||
if (!kbUseSubsetSps) {
|
||||
pSps = & (pCtx->pSpsArray[kiFoundSpsId]);
|
||||
} else {
|
||||
pSubsetSps = & (pCtx->pSubsetArray[kiFoundSpsId]);
|
||||
}
|
||||
} else {
|
||||
//if no, generate a new SPS as usual
|
||||
if (!CheckPpsGenerating()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
kuiSpsId = (!kbUseSubsetSps) ? (m_sParaSetOffset.uiInUseSpsNum++) : (m_sParaSetOffset.uiInUseSubsetSpsNum++);
|
||||
if (kuiSpsId >= MAX_SPS_COUNT) {
|
||||
if (SpsReset (pCtx, kbUseSubsetSps) < 0) {
|
||||
return -1;
|
||||
}
|
||||
kuiSpsId = 0;
|
||||
}
|
||||
|
||||
WelsGenerateNewSps (pCtx, kbUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, kuiSpsId, pSps, pSubsetSps, bSvcBaselayer);
|
||||
}
|
||||
return kuiSpsId;
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsListing::UpdateParaSetNum (sWelsEncCtx* pCtx) {
|
||||
pCtx->iSpsNum = m_sParaSetOffset.uiInUseSpsNum;
|
||||
pCtx->iSubsetSpsNum = m_sParaSetOffset.uiInUseSubsetSpsNum;
|
||||
};
|
||||
|
||||
void CWelsParametersetSpsListing::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
|
||||
int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
|
||||
CWelsParametersetIdNonConstant::OutputCurrentStructure (pParaSetOffsetVariable, pPpsIdList, pCtx, pExistingParasetList);
|
||||
pExistingParasetList->uiInUseSpsNum = m_sParaSetOffset.uiInUseSpsNum;
|
||||
|
||||
memcpy (pExistingParasetList->sSps, pCtx->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||
if (NULL != pCtx->pSubsetArray) {
|
||||
pExistingParasetList->uiInUseSubsetSpsNum = m_sParaSetOffset.uiInUseSubsetSpsNum;
|
||||
memcpy (pExistingParasetList->sSubsetSps, pCtx->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||
} else {
|
||||
pExistingParasetList->uiInUseSubsetSpsNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//CWelsParametersetSpsPpsListing
|
||||
//
|
||||
|
||||
CWelsParametersetSpsPpsListing::CWelsParametersetSpsPpsListing (const bool bSimulcastAVC,
|
||||
const int32_t kiSpatialLayerNum): CWelsParametersetSpsListing (bSimulcastAVC, kiSpatialLayerNum) {
|
||||
memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
|
||||
|
||||
m_bSimulcastAVC = bSimulcastAVC;
|
||||
m_iSpatialLayerNum = kiSpatialLayerNum;
|
||||
|
||||
m_iBasicNeededSpsNum = MAX_SPS_COUNT;
|
||||
m_iBasicNeededPpsNum = MAX_PPS_COUNT;
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsPpsListing::LoadPreviousPps (SExistingParasetList* pExistingParasetList, SWelsPPS* pPpsArray) {
|
||||
// copy from existing if the pointer exists
|
||||
//if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
|
||||
m_sParaSetOffset.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
|
||||
memcpy (pPpsArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||
//}
|
||||
}
|
||||
|
||||
/* if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
|
||||
UpdatePpsList (pCtx);
|
||||
}*/
|
||||
void CWelsParametersetSpsPpsListing::UpdatePpsList (sWelsEncCtx* pCtx) {
|
||||
if (pCtx->iPpsNum >= MAX_PPS_COUNT) {
|
||||
return;
|
||||
}
|
||||
assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
|
||||
|
||||
//Generate PPS LIST
|
||||
int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
|
||||
|
||||
for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
|
||||
for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
|
||||
m_sParaSetOffset.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
|
||||
memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
|
||||
pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
|
||||
pCtx->iPpsNum++;
|
||||
}
|
||||
|
||||
assert (pCtx->iPpsNum == MAX_PPS_COUNT);
|
||||
m_sParaSetOffset.uiInUsePpsNum = pCtx->iPpsNum;
|
||||
}
|
||||
|
||||
|
||||
bool CWelsParametersetSpsPpsListing::CheckPpsGenerating() {
|
||||
/*if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (MAX_PPS_COUNT <= pCtx->sPSOVector.uiInUsePpsNum)) {
|
||||
//check if we can generate new SPS or not
|
||||
WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR,
|
||||
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}*/
|
||||
if (MAX_PPS_COUNT <= m_sParaSetOffset.uiInUsePpsNum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
int32_t CWelsParametersetSpsPpsListing::SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps) {
|
||||
/* if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) {
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId,
|
||||
const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse,
|
||||
SWelsPPS* pPpsArray) {
|
||||
#if !defined(DISABLE_FMO_FEATURE)
|
||||
// feature not supported yet
|
||||
return INVALID_ID;
|
||||
#endif//!DISABLE_FMO_FEATURE
|
||||
|
||||
SWelsPPS sTmpPps;
|
||||
WelsInitPps (&sTmpPps,
|
||||
pSps,
|
||||
pSubsetSps,
|
||||
0,
|
||||
true,
|
||||
kbUseSubsetSps,
|
||||
kbEntropyCodingFlag);
|
||||
|
||||
assert (iPpsNumInUse <= MAX_PPS_COUNT);
|
||||
for (int32_t iId = 0; iId < iPpsNumInUse; iId++) {
|
||||
if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId)
|
||||
&& (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag)
|
||||
&& (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp)
|
||||
&& (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs)
|
||||
&& (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset)
|
||||
&& (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag)
|
||||
) {
|
||||
return iId;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
uint32_t CWelsParametersetSpsPpsListing::InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
|
||||
SWelsSPS* pSps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag) {
|
||||
const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, kbUsingSubsetSps, kiSpsId,
|
||||
kbEntropyCodingModeFlag,
|
||||
m_sParaSetOffset.uiInUsePpsNum,
|
||||
pCtx->pPPSArray);
|
||||
|
||||
|
||||
if (INVALID_ID != kiFoundPpsId) {
|
||||
//if yes, set pPps to it
|
||||
kuiPpsId = kiFoundPpsId;
|
||||
} else {
|
||||
kuiPpsId = (m_sParaSetOffset.uiInUsePpsNum++);
|
||||
WelsInitPps (& pCtx->pPPSArray[kuiPpsId], pSps, pSubsetSps, kuiPpsId, true, kbUsingSubsetSps, kbEntropyCodingModeFlag);
|
||||
}
|
||||
SetUseSubsetFlag (kuiPpsId, kbUsingSubsetSps);
|
||||
return kuiPpsId;
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsPpsListing::UpdateParaSetNum (sWelsEncCtx* pCtx) {
|
||||
CWelsParametersetSpsListing::UpdateParaSetNum (pCtx);
|
||||
|
||||
//UpdatePpsList (pCtx);
|
||||
pCtx->iPpsNum = m_sParaSetOffset.uiInUsePpsNum;
|
||||
}
|
||||
|
||||
int32_t CWelsParametersetSpsPpsListing::GetCurrentPpsId (const int32_t iPpsId, const int32_t iIdrLoop) {
|
||||
return m_sParaSetOffset.iPpsIdList[iPpsId][iIdrLoop];
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsPpsListing::LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
|
||||
int32_t* pPpsIdList) {
|
||||
memcpy (m_sParaSetOffset.sParaSetOffsetVariable, pParaSetOffsetVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
|
||||
memcpy ((m_sParaSetOffset.iPpsIdList), pPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsPpsListing::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
|
||||
int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
|
||||
CWelsParametersetSpsListing::OutputCurrentStructure (pParaSetOffsetVariable, pPpsIdList, pCtx, pExistingParasetList);
|
||||
|
||||
pExistingParasetList->uiInUsePpsNum = m_sParaSetOffset.uiInUsePpsNum;
|
||||
memcpy (pExistingParasetList->sPps, pCtx->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||
memcpy (pPpsIdList, (m_sParaSetOffset.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||
}
|
||||
|
||||
//
|
||||
//CWelsParametersetSpsListingPpsIncreasing
|
||||
//
|
||||
|
||||
int32_t CWelsParametersetSpsListingPpsIncreasing::GetPpsIdOffset (const int32_t kiPpsId) {
|
||||
//same as CWelsParametersetIdIncreasing::GetPpsIdOffset
|
||||
return (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId]);
|
||||
}
|
||||
|
||||
void CWelsParametersetSpsListingPpsIncreasing::Update (const uint32_t kuiId, const int iParasetType) {
|
||||
//same as CWelsParametersetIdIncreasing::Update
|
||||
#if _DEBUG
|
||||
assert (kuiId < MAX_DQ_LAYER_NUM);
|
||||
#endif
|
||||
|
||||
ParasetIdAdditionIdAdjust (& (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType]),
|
||||
kuiId,
|
||||
(iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ namespace WelsEnc {
|
||||
|
||||
typedef int32_t (*PWelsCodingSliceFunc) (sWelsEncCtx* pCtx, SSlice* pSlice);
|
||||
typedef void (*PWelsSliceHeaderWriteFunc) (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
|
||||
int32_t* pPpsIdDelta);
|
||||
IWelsParametersetStrategy* pParametersetStrategy);
|
||||
|
||||
void UpdateNonZeroCountCache (SMB* pMb, SMbCache* pMbCache) {
|
||||
ST32 (&pMbCache->iNonZeroCoeffCount[9], LD32 (&pMb->pNonZeroCount[ 0]));
|
||||
@ -276,7 +276,7 @@ void WriteRefPicMarking (SBitStringAux* pBs, SSliceHeader* pSliceHeader, SNalUni
|
||||
}
|
||||
|
||||
void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
|
||||
int32_t* pPpsIdDelta) {
|
||||
IWelsParametersetStrategy* pParametersetStrategy) {
|
||||
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
||||
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
||||
SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
|
||||
@ -285,7 +285,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
|
||||
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
||||
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
||||
|
||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
|
||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pParametersetStrategy->GetPpsIdOffset (pSliceHeader->pPps->iPpsId));
|
||||
|
||||
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
||||
|
||||
@ -342,7 +342,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
|
||||
}
|
||||
|
||||
void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
|
||||
int32_t* pPpsIdDelta) {
|
||||
IWelsParametersetStrategy* pParametersetStrategy) {
|
||||
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
||||
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
||||
SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;
|
||||
@ -353,7 +353,8 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p
|
||||
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
||||
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
||||
|
||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
|
||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId +
|
||||
pParametersetStrategy->GetPpsIdOffset (pSliceHeader->pPps->iPpsId));
|
||||
|
||||
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
||||
|
||||
@ -926,20 +927,7 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
|
||||
WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
|
||||
|
||||
g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,
|
||||
((SPS_PPS_LISTING != pEncCtx->pSvcParam->eSpsPpsIdStrategy) ? (&
|
||||
(pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL));
|
||||
|
||||
#if _DEBUG
|
||||
if (INCREASING_ID & pEncCtx->sPSOVector.eSpsPpsIdStrategy) {
|
||||
const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;
|
||||
const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +
|
||||
pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];
|
||||
assert (MAX_PPS_COUNT > kiTmpPpsIdInBs);
|
||||
|
||||
//when activated need to sure there is avialable PPS
|
||||
assert (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].bUsedParaSetIdInBs[kiTmpPpsIdInBs]);
|
||||
}
|
||||
#endif
|
||||
pEncCtx->pFuncList->pParametersetStrategy);
|
||||
|
||||
pCurSlice->uiLastMbQp = pCurLayer->sLayerInfo.pPpsP->iPicInitQp + pCurSlice->sSliceHeaderExt.sSliceHeader.iSliceQpDelta;
|
||||
|
||||
|
@ -11,6 +11,7 @@ ENCODER_CPP_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/src/md.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/mv_pred.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/nal_encap.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/paraset_strategy.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/picture_handle.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/ratectl.cpp\
|
||||
$(ENCODER_SRCDIR)/core/src/ref_list_mgr_svc.cpp\
|
||||
|
@ -34,7 +34,8 @@
|
||||
#include "cpu.h"
|
||||
|
||||
WELSVP_NAMESPACE_BEGIN
|
||||
|
||||
#define MAX_SAMPLE_WIDTH 1920
|
||||
#define MAX_SAMPLE_HEIGHT 1088
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -43,11 +44,37 @@ CDownsampling::CDownsampling (int32_t iCpuFlag) {
|
||||
m_eMethod = METHOD_DOWNSAMPLE;
|
||||
WelsMemset (&m_pfDownsample, 0, sizeof (m_pfDownsample));
|
||||
InitDownsampleFuncs (m_pfDownsample, m_iCPUFlag);
|
||||
m_bNoSampleBuffer = AllocateSampleBuffer();
|
||||
}
|
||||
|
||||
CDownsampling::~CDownsampling() {
|
||||
FreeSampleBuffer();
|
||||
}
|
||||
bool CDownsampling::AllocateSampleBuffer() {
|
||||
for (int32_t i = 0; i < 2; i++) {
|
||||
m_pSampleBuffer[i][0] = (uint8_t*)WelsMalloc (MAX_SAMPLE_WIDTH * MAX_SAMPLE_HEIGHT);
|
||||
if (!m_pSampleBuffer[i][0])
|
||||
goto FREE_RET;
|
||||
m_pSampleBuffer[i][1] = (uint8_t*)WelsMalloc (MAX_SAMPLE_WIDTH * MAX_SAMPLE_HEIGHT / 4);
|
||||
if (!m_pSampleBuffer[i][1])
|
||||
goto FREE_RET;
|
||||
m_pSampleBuffer[i][2] = (uint8_t*)WelsMalloc (MAX_SAMPLE_WIDTH * MAX_SAMPLE_HEIGHT / 4);
|
||||
if (!m_pSampleBuffer[i][2])
|
||||
goto FREE_RET;
|
||||
}
|
||||
return false;
|
||||
FREE_RET:
|
||||
FreeSampleBuffer();
|
||||
return true;
|
||||
|
||||
}
|
||||
void CDownsampling::FreeSampleBuffer() {
|
||||
for (int32_t i = 0; i < 2; i++) {
|
||||
WelsFree (m_pSampleBuffer[i][0]);
|
||||
WelsFree (m_pSampleBuffer[i][1]);
|
||||
WelsFree (m_pSampleBuffer[i][2]);
|
||||
}
|
||||
}
|
||||
void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag) {
|
||||
sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsampler_c;
|
||||
sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsampler_c;
|
||||
@ -123,49 +150,132 @@ EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDs
|
||||
if (iSrcWidthY <= iDstWidthY || iSrcHeightY <= iDstHeightY) {
|
||||
return RET_INVALIDPARAM;
|
||||
}
|
||||
if (iSrcWidthY > MAX_SAMPLE_WIDTH || iSrcHeightY > MAX_SAMPLE_HEIGHT || m_bNoSampleBuffer) {
|
||||
if ((iSrcWidthY >> 1) == iDstWidthY && (iSrcHeightY >> 1) == iDstHeightY) {
|
||||
// use half average functions
|
||||
uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
|
||||
|
||||
if ((iSrcWidthY >> 1) == iDstWidthY && (iSrcHeightY >> 1) == iDstHeightY) {
|
||||
// use half average functions
|
||||
uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
|
||||
iAlignIndex = GetAlignedIndex (iSrcWidthUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
} else if ((iSrcWidthY >> 2) == iDstWidthY && (iSrcHeightY >> 2) == iDstHeightY) {
|
||||
|
||||
iAlignIndex = GetAlignedIndex (iSrcWidthUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
} else if ((iSrcWidthY >> 2) == iDstWidthY && (iSrcHeightY >> 2) == iDstHeightY) {
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
|
||||
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
} else if ((iSrcWidthY / 3) == iDstWidthY && (iSrcHeightY / 3) == iDstHeightY) {
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iDstHeightY);
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iDstHeightUV);
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iDstHeightUV);
|
||||
|
||||
} else {
|
||||
m_pfDownsample.pfGeneralRatioLuma ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0], iDstWidthY, iDstHeightY,
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
|
||||
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
m_pfDownsample.pfQuarterDownsampler ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
} else if ((iSrcWidthY / 3) == iDstWidthY && (iSrcHeightY / 3) == iDstHeightY) {
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iDstHeightY);
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iDstHeightUV);
|
||||
|
||||
m_pfDownsample.pfOneThirdDownsampler ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iDstHeightUV);
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
}
|
||||
} else {
|
||||
m_pfDownsample.pfGeneralRatioLuma ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0], iDstWidthY, iDstHeightY,
|
||||
(uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
|
||||
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
|
||||
int32_t iIdx = 0;
|
||||
int32_t iHalfSrcWidth = iSrcWidthY >> 1;
|
||||
int32_t iHalfSrcHeight = iSrcHeightY >> 1;
|
||||
uint8_t* pSrcY = (uint8_t*)pSrcPixMap->pPixel[0];
|
||||
uint8_t* pSrcU = (uint8_t*)pSrcPixMap->pPixel[1];
|
||||
uint8_t* pSrcV = (uint8_t*)pSrcPixMap->pPixel[2];
|
||||
int32_t iSrcStrideY = pSrcPixMap->iStride[0];
|
||||
int32_t iSrcStrideU = pSrcPixMap->iStride[1];
|
||||
int32_t iSrcStrideV = pSrcPixMap->iStride[2];
|
||||
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
|
||||
int32_t iDstStrideY = pDstPixMap->iStride[0];
|
||||
int32_t iDstStrideU = pDstPixMap->iStride[1];
|
||||
int32_t iDstStrideV = pDstPixMap->iStride[2];
|
||||
|
||||
uint8_t* pDstY = (uint8_t*)m_pSampleBuffer[iIdx][0];
|
||||
uint8_t* pDstU = (uint8_t*)m_pSampleBuffer[iIdx][1];
|
||||
uint8_t* pDstV = (uint8_t*)m_pSampleBuffer[iIdx][2];
|
||||
iIdx++;
|
||||
do {
|
||||
if ((iHalfSrcWidth == iDstWidthY) && (iHalfSrcHeight == iDstHeightY)) { //end
|
||||
// use half average functions
|
||||
uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
|
||||
(uint8_t*)pSrcY, iSrcStrideY, iSrcWidthY, iSrcHeightY);
|
||||
|
||||
iAlignIndex = GetAlignedIndex (iSrcWidthUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
|
||||
(uint8_t*)pSrcU, iSrcStrideU, iSrcWidthUV, iSrcHeightUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
|
||||
(uint8_t*)pSrcV, iSrcStrideV, iSrcWidthUV, iSrcHeightUV);
|
||||
break;
|
||||
} else if (((iHalfSrcWidth >> 1) >= iDstWidthY) && ((iHalfSrcHeight >> 1) >= iDstHeightY)) {
|
||||
// use half average functions
|
||||
iDstStrideY = iHalfSrcWidth;
|
||||
iDstStrideU = iHalfSrcWidth >> 1;
|
||||
iDstStrideV = iHalfSrcWidth >> 1;
|
||||
uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstY, iDstStrideY,
|
||||
(uint8_t*)pSrcY, iSrcStrideY, iSrcWidthY, iSrcHeightY);
|
||||
|
||||
iAlignIndex = GetAlignedIndex (iSrcWidthUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstU, iDstStrideU,
|
||||
(uint8_t*)pSrcU, iSrcStrideU, iSrcWidthUV, iSrcHeightUV);
|
||||
m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstV, iDstStrideV,
|
||||
(uint8_t*)pSrcV, iSrcStrideV, iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
pSrcY = (uint8_t*)pDstY;
|
||||
pSrcU = (uint8_t*)pDstU;
|
||||
pSrcV = (uint8_t*)pDstV;
|
||||
|
||||
|
||||
iSrcWidthY = iHalfSrcWidth;
|
||||
iSrcWidthUV = iHalfSrcWidth >> 1;
|
||||
iSrcHeightY = iHalfSrcHeight;
|
||||
iSrcHeightUV = iHalfSrcHeight >> 1;
|
||||
|
||||
iSrcStrideY = iSrcWidthY;
|
||||
iSrcStrideU = iSrcWidthUV;
|
||||
iSrcStrideV = iSrcWidthUV;
|
||||
|
||||
iHalfSrcWidth >>= 1;
|
||||
iHalfSrcHeight >>= 1;
|
||||
|
||||
iIdx = iIdx % 2;
|
||||
pDstY = (uint8_t*)m_pSampleBuffer[iIdx][0];
|
||||
pDstU = (uint8_t*)m_pSampleBuffer[iIdx][1];
|
||||
pDstV = (uint8_t*)m_pSampleBuffer[iIdx][2];
|
||||
iIdx++;
|
||||
} else {
|
||||
m_pfDownsample.pfGeneralRatioLuma ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0], iDstWidthY, iDstHeightY,
|
||||
(uint8_t*)pSrcY, iSrcStrideY, iSrcWidthY, iSrcHeightY);
|
||||
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcU, iSrcStrideU, iSrcWidthUV, iSrcHeightUV);
|
||||
|
||||
m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2], iDstWidthUV, iDstHeightUV,
|
||||
(uint8_t*)pSrcV, iSrcStrideV, iSrcWidthUV, iSrcHeightUV);
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
@ -170,10 +170,13 @@ class CDownsampling : public IStrategy {
|
||||
void InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag);
|
||||
|
||||
int32_t GetAlignedIndex (const int32_t kiSrcWidth);
|
||||
|
||||
bool AllocateSampleBuffer();
|
||||
void FreeSampleBuffer();
|
||||
private:
|
||||
SDownsampleFuncs m_pfDownsample;
|
||||
int32_t m_iCPUFlag;
|
||||
uint8_t *m_pSampleBuffer[2][3];
|
||||
bool m_bNoSampleBuffer;
|
||||
};
|
||||
|
||||
WELSVP_NAMESPACE_END
|
||||
|
@ -385,7 +385,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_INCREASING_ID) {
|
||||
//prepare output if needed
|
||||
FILE* fEnc = NULL;
|
||||
#ifdef DEBUG_FILE_SAVE_INCREASING_ID
|
||||
fEnc = fopen ("enc_i.264", "wb");
|
||||
fEnc = fopen ("enc_INCREASING_ID.264", "wb");
|
||||
#endif
|
||||
|
||||
// Test part#1
|
||||
@ -440,7 +440,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_INCREASING_ID) {
|
||||
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE_INCREASING_ID
|
||||
fEnc = fopen ("enc3.264", "wb");
|
||||
fEnc = fopen ("enc_INCREASING_ID2.264", "wb");
|
||||
#endif
|
||||
iEncFrameNum = 0;
|
||||
EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
|
||||
@ -495,7 +495,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING
|
||||
//prepare output if needed
|
||||
FILE* fEnc = NULL;
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
fEnc = fopen ("enc2.264", "wb");
|
||||
fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING1.264", "wb");
|
||||
#endif
|
||||
|
||||
// Test part#1
|
||||
@ -550,7 +550,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING
|
||||
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
fEnc = fopen ("enc3.264", "wb");
|
||||
fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING11.264", "wb");
|
||||
#endif
|
||||
iEncFrameNum = 0;
|
||||
EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
|
||||
@ -598,7 +598,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING
|
||||
//prepare output if needed
|
||||
FILE* fEnc = NULL;
|
||||
#ifdef DEBUG_FILE_SAVE5
|
||||
fEnc = fopen ("encID2.264", "wb");
|
||||
fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING2.264", "wb");
|
||||
#endif
|
||||
|
||||
// step#1: pParam1
|
||||
@ -647,7 +647,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING
|
||||
//prepare output if needed
|
||||
FILE* fEnc = NULL;
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
fEnc = fopen ("enc4.264", "wb");
|
||||
fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING3.264", "wb");
|
||||
#endif
|
||||
|
||||
// step#1: pParam1
|
||||
@ -853,7 +853,7 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
|
||||
//prepare output if needed
|
||||
FILE* fEnc = NULL;
|
||||
#ifdef DEBUG_FILE_SAVE5
|
||||
fEnc = fopen ("enc4.264", "wb");
|
||||
fEnc = fopen ("enc_LISTING3.264", "wb");
|
||||
#endif
|
||||
|
||||
// step#1: ordinary encoding
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "param_svc.h"
|
||||
#include "parameter_sets.h"
|
||||
#include "wels_const.h"
|
||||
#include "paraset_strategy.h"
|
||||
|
||||
using namespace WelsEnc;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user