Merge pull request #2206 from sijchen/thp42
[Encoder] adjust encoder tasks, add ut and enable new thread pool under some cases
This commit is contained in:
commit
b0c6ea9385
@ -112,6 +112,18 @@ class CWelsCircleQueue {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TNodeType* GetIndexNode (const int32_t iIdx) {
|
||||
if (size() > 0) {
|
||||
if ((iIdx + m_iCurrentListStart) < m_iMaxNodeCount) {
|
||||
return m_pCurrentQueue[m_iCurrentListStart + iIdx];
|
||||
} else {
|
||||
return m_pCurrentQueue[m_iCurrentListStart + iIdx - m_iMaxNodeCount];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t InternalPushBack (TNodeType* pNode) {
|
||||
m_pCurrentQueue[m_iCurrentListEnd] = pNode;
|
||||
|
@ -313,6 +313,7 @@ WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT* p_event, const char* event_
|
||||
*p_event = NULL;
|
||||
return WELS_THREAD_ERROR_GENERAL;
|
||||
} else {
|
||||
//printf("event_open:%x, %s\n", p_event, event_name);
|
||||
return WELS_THREAD_ERROR_OK;
|
||||
}
|
||||
#else
|
||||
@ -329,6 +330,7 @@ WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT* p_event, const char* event_
|
||||
#endif
|
||||
}
|
||||
WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, const char* event_name) {
|
||||
//printf("event_close:%x, %s\n", event, event_name);
|
||||
#ifdef __APPLE__
|
||||
WELS_THREAD_ERROR_CODE err = sem_close (*event); // match with sem_open
|
||||
if (event_name)
|
||||
|
@ -57,6 +57,7 @@
|
||||
|
||||
#include "mt_defs.h" // for multiple threadin,
|
||||
#include "WelsThreadLib.h"
|
||||
#include "wels_task_management.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
@ -134,7 +135,7 @@ typedef struct TagWelsEncCtx {
|
||||
SWelsFuncPtrList* pFuncList;
|
||||
|
||||
SSliceThreading* pSliceThreading;
|
||||
//IWelsTaskManage* pTaskManage; //was planning to put it under CWelsH264SVCEncoder but it may be updated (lock/no lock) when param is changed
|
||||
IWelsTaskManage* pTaskManage; //was planning to put it under CWelsH264SVCEncoder but it may be updated (lock/no lock) when param is changed
|
||||
|
||||
// SSlice context
|
||||
SSliceCtx* pSliceCtxList;// slice context table for each dependency quality layer
|
||||
|
@ -61,6 +61,7 @@ class CWelsSliceEncodingTask : public CWelsBaseTask {
|
||||
|
||||
virtual WelsErrorType Execute();
|
||||
virtual WelsErrorType InitTask();
|
||||
virtual WelsErrorType ExecuteTask();
|
||||
virtual void FinishTask();
|
||||
|
||||
virtual uint32_t GetTaskType() const {
|
||||
|
@ -56,7 +56,7 @@ class IWelsTaskManage {
|
||||
virtual WelsErrorType Init (sWelsEncCtx* pEncCtx) = 0;
|
||||
virtual void Uninit() = 0;
|
||||
|
||||
virtual void InitFrame() {}
|
||||
virtual void InitFrame (const int32_t kiCurDid) {}
|
||||
virtual WelsErrorType ExecuteTasks() = 0;
|
||||
|
||||
static IWelsTaskManage* CreateTaskManage (sWelsEncCtx* pCtx, bool bNeedLock);
|
||||
@ -75,7 +75,7 @@ class CWelsTaskManageBase : public IWelsTaskManage, public WelsCommon::IWelsThr
|
||||
virtual WelsErrorType Init (sWelsEncCtx* pEncCtx);
|
||||
void Uninit();
|
||||
|
||||
virtual void InitFrame();
|
||||
virtual void InitFrame (const int32_t kiCurDid);
|
||||
virtual WelsErrorType ExecuteTasks();
|
||||
|
||||
//IWelsThreadPoolSink
|
||||
@ -88,13 +88,13 @@ class CWelsTaskManageBase : public IWelsTaskManage, public WelsCommon::IWelsThr
|
||||
|
||||
protected:
|
||||
sWelsEncCtx* m_pEncCtx;
|
||||
WelsCommon::CWelsThreadPool* m_pThreadPool;
|
||||
|
||||
TASKLIST_TYPE* m_cTaskList;
|
||||
int32_t m_iTaskNum;
|
||||
|
||||
//SLICE_PAIR_LIST *m_cSliceList;
|
||||
|
||||
WelsCommon::CWelsThreadPool* m_pThreadPool;
|
||||
int32_t m_iThreadNum;
|
||||
|
||||
int32_t m_iWaitTaskNum;
|
||||
@ -104,6 +104,7 @@ class CWelsTaskManageBase : public IWelsTaskManage, public WelsCommon::IWelsThr
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (CWelsTaskManageBase);
|
||||
void OnTaskMinusOne();
|
||||
};
|
||||
|
||||
class CWelsTaskManageOne : public CWelsTaskManageBase {
|
||||
|
@ -2930,6 +2930,10 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
|
||||
} else {
|
||||
pCurDq->bBaseLayerAvailableFlag = false;
|
||||
}
|
||||
|
||||
if (pCtx->pTaskManage) {
|
||||
pCtx->pTaskManage->InitFrame(kiCurDid);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetFastCodingFunc (SWelsFuncPtrList* pFuncList) {
|
||||
@ -4016,7 +4020,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
iSliceCount);
|
||||
return ENC_RETURN_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (SM_AUTO_SLICE == pParam->sSliceCfg.uiSliceMode) {
|
||||
if (pSvcParam->iCountThreadsNum >= iSliceCount) { //THREAD_FULLY_FIRE_MODE
|
||||
#if defined(MT_DEBUG)
|
||||
int64_t t_bs_append = 0;
|
||||
@ -4105,6 +4109,19 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
// append exclusive slice 0 bs to pFrameBs
|
||||
iLayerSize = AppendSliceToFrameBs (pCtx, pLayerBsInfo, iSliceCount);
|
||||
}
|
||||
|
||||
} else {
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->uiLayerType = VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->uiSpatialId = pCtx->uiDependencyId;
|
||||
pLayerBsInfo->uiTemporalId = pCtx->uiTemporalId;
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->iNalCount = 0;
|
||||
pCtx->pSliceBs[0].pBs = pLayerBsInfo->pBsBuf;
|
||||
|
||||
pCtx->pTaskManage->ExecuteTasks();
|
||||
iLayerSize = AppendSliceToFrameBs (pCtx, pLayerBsInfo, iSliceCount);
|
||||
}
|
||||
}
|
||||
// THREAD_FULLY_FIRE_MODE && SM_DYN_SLICE
|
||||
else if ((SM_DYN_SLICE == pParam->sSliceCfg.uiSliceMode) && (pSvcParam->iMultipleThreadIdc > 1)) {
|
||||
|
@ -333,6 +333,7 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
|
||||
int32_t iIdx = 0;
|
||||
int16_t iMaxSliceNum = 1;
|
||||
int32_t iReturn = ENC_RETURN_SUCCESS;
|
||||
bool bWillUseTaskManage = false;
|
||||
|
||||
if (NULL == ppCtx || NULL == pCodingParam || NULL == *ppCtx || iCountBsLen <= 0)
|
||||
return 1;
|
||||
@ -372,6 +373,10 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
|
||||
pSmt->pSliceConsumeTime[iIdx] = NULL;
|
||||
pSmt->pSliceComplexRatio[iIdx] = NULL;
|
||||
}
|
||||
|
||||
if ( pMso->uiSliceMode == SM_FIXEDSLCNUM_SLICE || pMso->uiSliceMode == SM_RASTER_SLICE || pMso->uiSliceMode == SM_ROWMB_SLICE) {
|
||||
bWillUseTaskManage = true;
|
||||
}
|
||||
++ iIdx;
|
||||
}
|
||||
// NULL for pSliceConsumeTime[iIdx]: iIdx from iNumSpatialLayers to MAX_DEPENDENCY_LAYERS
|
||||
@ -430,9 +435,11 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
|
||||
pSmt->pThreadBsBuffer[iIdx] = NULL;
|
||||
}
|
||||
|
||||
//previous conflict
|
||||
WelsSnprintf (name, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
|
||||
err = WelsEventOpen (&pSmt->pSliceCodedMasterEvent, name);
|
||||
MT_TRACE_LOG (*ppCtx, WELS_LOG_INFO, "[MT] Open pSliceCodedMasterEvent named(%s) ret%d err%d", name, err, errno);
|
||||
//previous conflict ends
|
||||
|
||||
|
||||
iReturn = SetMultiSliceBuffer (ppCtx, pMa, pSmt, iMaxSliceNum,
|
||||
@ -444,6 +451,11 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
|
||||
iReturn = WelsMutexInit (&pSmt->mutexSliceNumUpdate);
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
|
||||
|
||||
if (bWillUseTaskManage) {
|
||||
(*ppCtx)->pTaskManage = IWelsTaskManage::CreateTaskManage(*ppCtx, bDynamicSlice);
|
||||
WELS_VERIFY_RETURN_PROC_IF (iReturn, (NULL == (*ppCtx)->pTaskManage), FreeMemorySvc (ppCtx))
|
||||
}
|
||||
|
||||
memset(&pSmt->bThreadBsBufferUsage, 0, MAX_THREADS_NUM * sizeof(bool));
|
||||
iReturn = WelsMutexInit (&pSmt->mutexThreadBsBufferUsage);
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
|
||||
@ -530,6 +542,12 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) {
|
||||
pMa->WelsFree ((*ppCtx)->pSliceBs, "pSliceBs");
|
||||
(*ppCtx)->pSliceBs = NULL;
|
||||
}
|
||||
|
||||
if ((*ppCtx)->pTaskManage != NULL) {
|
||||
delete (*ppCtx)->pTaskManage;
|
||||
(*ppCtx)->pTaskManage = NULL;
|
||||
}
|
||||
|
||||
iIdx = 0;
|
||||
while (iIdx < pCodingParam->iSpatialLayerNum) {
|
||||
if (pSmt->pSliceConsumeTime[iIdx]) {
|
||||
@ -1171,6 +1189,7 @@ void TrackSliceConsumeTime (sWelsEncCtx* pCtx, int32_t* pDidList, const int32_t
|
||||
void SetOneSliceBsBufferUnderMultithread (sWelsEncCtx* pCtx, const int32_t kiThreadIdx, const int32_t iSliceIdx) {
|
||||
pCtx->pSliceBs[iSliceIdx].pBsBuffer = pCtx->pSliceThreading->pThreadBsBuffer[kiThreadIdx];
|
||||
pCtx->pSliceBs[iSliceIdx].uiBsPos = 0;
|
||||
//printf("SetOneSliceBsBufferUnderMultithread, thread %d, slice %d, buffer=%x\n", kiThreadIdx, iSliceIdx, pCtx->pSliceBs[iSliceIdx].pBsBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,18 @@ CWelsSliceEncodingTask::CWelsSliceEncodingTask (sWelsEncCtx* pCtx, const int32_t
|
||||
CWelsSliceEncodingTask::~CWelsSliceEncodingTask() {
|
||||
}
|
||||
|
||||
WelsErrorType CWelsSliceEncodingTask::Execute() {
|
||||
WelsThreadSetName ("OpenH264Enc_CWelsSliceEncodingTask_Execute");
|
||||
|
||||
int32_t iReturn = InitTask();
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
|
||||
iReturn = ExecuteTask();
|
||||
|
||||
FinishTask();
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
WelsErrorType CWelsSliceEncodingTask::SetBoundary (int32_t iStartIdx, int32_t iEndIdx) {
|
||||
m_iStartMbIdx = iStartIdx;
|
||||
m_iEndMbIdx = iEndIdx;
|
||||
@ -88,10 +100,11 @@ WelsErrorType CWelsSliceEncodingTask::InitTask() {
|
||||
m_iThreadIdx = QueryEmptyThread (m_pCtx->pSliceThreading->bThreadBsBufferUsage);
|
||||
WelsMutexUnlock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);
|
||||
if (m_iThreadIdx < 0) {
|
||||
printf ("cannot find avaialble thread %d\n", m_iThreadIdx);
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CWelsSliceEncodingTask InitTask(), Cannot find available thread for m_iSliceIdx = %d", m_iSliceIdx);
|
||||
return ENC_RETURN_UNEXPECTED;
|
||||
}
|
||||
SetOneSliceBsBufferUnderMultithread (m_pCtx, m_iSliceIdx, m_iThreadIdx);
|
||||
SetOneSliceBsBufferUnderMultithread (m_pCtx, m_iThreadIdx, m_iSliceIdx);
|
||||
|
||||
m_pSlice = &m_pCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[m_iSliceIdx];
|
||||
m_pSliceBs = &m_pCtx->pSliceBs[m_iSliceIdx];
|
||||
@ -101,18 +114,18 @@ WelsErrorType CWelsSliceEncodingTask::InitTask() {
|
||||
|
||||
assert ((void*) (&m_pSliceBs->sBsWrite) == (void*)m_pSlice->pSliceBsa);
|
||||
InitBits (&m_pSliceBs->sBsWrite, m_pSliceBs->pBsBuffer, m_pSliceBs->uiSize);
|
||||
//printf ("CWelsSliceEncodingTask_InitTask slice %d\n", m_iSliceIdx);
|
||||
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
void CWelsSliceEncodingTask::FinishTask() {
|
||||
WelsMutexLock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);
|
||||
m_pCtx->pSliceThreading->bThreadBsBufferUsage[m_iThreadIdx] = false;
|
||||
WelsMutexUnlock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);
|
||||
}
|
||||
|
||||
WelsErrorType CWelsSliceEncodingTask::Execute() {
|
||||
WelsThreadSetName ("OpenH264Enc_CWelsSliceEncodingTask_Execute");
|
||||
|
||||
WelsErrorType CWelsSliceEncodingTask::ExecuteTask() {
|
||||
#if MT_DEBUG_BS_WR
|
||||
m_pSliceBs->bSliceCodedFlag = false;
|
||||
#endif//MT_DEBUG_BS_WR
|
||||
@ -144,6 +157,10 @@ WelsErrorType CWelsSliceEncodingTask::Execute() {
|
||||
iLeftBufferSize,
|
||||
m_iSliceIdx, m_iSliceSize);
|
||||
if (ENC_RETURN_SUCCESS != iReturn) {
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d",
|
||||
m_pCtx->iCodingIndex,
|
||||
m_iSliceIdx);
|
||||
return iReturn;
|
||||
}
|
||||
if (0 == m_iSliceIdx) {
|
||||
@ -152,15 +169,11 @@ WelsErrorType CWelsSliceEncodingTask::Execute() {
|
||||
|
||||
m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (m_pCtx->pCurDqLayer, m_pCtx->pFuncList, m_iSliceIdx);
|
||||
|
||||
#if defined(SLICE_INFO_OUTPUT)
|
||||
fprintf (stderr,
|
||||
"@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n",
|
||||
m_iSliceIdx,
|
||||
(pEncPEncCtx->eSliceType == P_SLICE ? 'P' : 'I'),
|
||||
eNalRefIdc,
|
||||
iSliceSize
|
||||
);
|
||||
#endif//SLICE_INFO_OUTPUT
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL,
|
||||
"@pSlice=%-6d sliceType:%c idc:%d size:%-6d", m_iSliceIdx,
|
||||
(m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'),
|
||||
m_eNalRefIdc,
|
||||
m_iSliceSize);
|
||||
|
||||
#if MT_DEBUG_BS_WR
|
||||
m_pSliceBs->bSliceCodedFlag = true;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "utils.h"
|
||||
#include "WelsLock.h"
|
||||
#include "memory_align.h"
|
||||
|
||||
@ -74,8 +75,8 @@ IWelsTaskManage* IWelsTaskManage::CreateTaskManage (sWelsEncCtx* pCtx, bool bN
|
||||
|
||||
CWelsTaskManageBase::CWelsTaskManageBase()
|
||||
: m_pEncCtx (NULL),
|
||||
m_iTaskNum (0),
|
||||
m_pThreadPool (NULL),
|
||||
m_iTaskNum (0),
|
||||
m_iWaitTaskNum (0) {
|
||||
m_cTaskList = new TASKLIST_TYPE();
|
||||
WelsEventOpen (&m_hTaskEvent);
|
||||
@ -120,8 +121,9 @@ WelsErrorType CWelsTaskManageBase::CreateTasks (sWelsEncCtx* pEncCtx, const int3
|
||||
}
|
||||
|
||||
void CWelsTaskManageBase::DestroyTasks() {
|
||||
if (m_iTaskNum == 0)
|
||||
if (m_iTaskNum == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cTaskList->size() != m_iTaskNum) {
|
||||
//printf("m_cTaskList %d %d\n", static_cast<int32_t>(m_cTaskList->size()), m_iTaskNum);
|
||||
@ -133,41 +135,47 @@ void CWelsTaskManageBase::DestroyTasks() {
|
||||
WELS_DELETE_OP (pTask);
|
||||
m_cTaskList->pop_front();
|
||||
}
|
||||
//WelsLog (&m_pEncCtx->sLogCtx, WELS_LOG_INFO,
|
||||
// "[MT] CWelsTaskManageParallel()DestroyTasks, cleaned %d tasks", m_iTaskNum);
|
||||
//printf ("[MT] CWelsTaskManageBase() DestroyTasks, cleaned %d tasks\n", m_iTaskNum);
|
||||
m_iTaskNum = 0;
|
||||
}
|
||||
|
||||
void CWelsTaskManageBase::InitFrame() {
|
||||
void CWelsTaskManageBase::OnTaskMinusOne() {
|
||||
WelsCommon::CWelsAutoLock cAutoLock (m_cWaitTaskNumLock);
|
||||
m_iWaitTaskNum --;
|
||||
if (m_iWaitTaskNum <= 0) {
|
||||
WelsEventSignal (&m_hTaskEvent);
|
||||
}
|
||||
//printf("OnTaskMinusOne m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
|
||||
}
|
||||
|
||||
WelsErrorType CWelsTaskManageBase::ExecuteTasks() {
|
||||
m_iWaitTaskNum = static_cast<int32_t> (m_cTaskList->size());
|
||||
while (NULL != m_cTaskList->begin()) {
|
||||
m_pThreadPool->QueueTask (m_cTaskList->begin());
|
||||
m_cTaskList->pop_front();
|
||||
}
|
||||
WelsEventWait (&m_hTaskEvent);
|
||||
|
||||
WelsErrorType CWelsTaskManageBase::OnTaskCancelled (WelsCommon::IWelsTask* pTask) {
|
||||
OnTaskMinusOne();
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
WelsErrorType CWelsTaskManageBase::OnTaskExecuted (WelsCommon::IWelsTask* pTask) {
|
||||
WelsCommon::CWelsAutoLock cAutoLock (m_cWaitTaskNumLock);
|
||||
m_iWaitTaskNum --;
|
||||
//WELS_INFO_TRACE("Waiting Task Num: " << m_iWaitTaskNum);
|
||||
if (m_iWaitTaskNum == 0) {
|
||||
WelsEventSignal (&m_hTaskEvent);
|
||||
//WELS_INFO_TRACE("Tasks over ");
|
||||
}
|
||||
|
||||
OnTaskMinusOne();
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
WelsErrorType CWelsTaskManageBase::OnTaskCancelled (WelsCommon::IWelsTask* pTask) {
|
||||
WelsCommon::CWelsAutoLock cAutoLock (m_cWaitTaskNumLock);
|
||||
m_iWaitTaskNum --;
|
||||
if (m_iWaitTaskNum == 0) {
|
||||
WelsEventSignal (&m_hTaskEvent);
|
||||
void CWelsTaskManageBase::InitFrame (const int32_t kiCurDid) {
|
||||
m_iWaitTaskNum = m_pEncCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceCfg.sSliceArgument.uiSliceNum;
|
||||
//printf("InitFrame m_iWaitTaskNum=%d, slice_mode=%d\n", m_iWaitTaskNum, m_pEncCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceCfg.uiSliceMode);
|
||||
//TODO: update mbmap;
|
||||
}
|
||||
|
||||
WelsErrorType CWelsTaskManageBase::ExecuteTasks() {
|
||||
//printf("ExecuteTasks m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
|
||||
int32_t iCurrentTaskCount = m_iWaitTaskNum; //if directly use m_iWaitTaskNum in the loop make cause sync problem
|
||||
int32_t iIdx = 0;
|
||||
while (iIdx < iCurrentTaskCount) {
|
||||
m_pThreadPool->QueueTask (m_cTaskList->GetIndexNode(iIdx));
|
||||
iIdx ++;
|
||||
}
|
||||
WelsEventWait (&m_hTaskEvent);
|
||||
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3727,4 +3727,133 @@ TEST_F (EncodeDecodeTestAPI, SimulcastAVCDiffFps) {
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
|
||||
int iSpatialLayerNum = 3;
|
||||
int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
|
||||
int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2), 2240);//TODO: use MAX_HEIGHT after the limit is removed
|
||||
float fFrameRate = rand() + 0.5f;
|
||||
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
||||
|
||||
// prepare params
|
||||
SEncParamExt sParam;
|
||||
encoder_->GetDefaultParams (&sParam);
|
||||
prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
|
||||
sParam.iMultipleThreadIdc = (rand() % 4) + 1;
|
||||
sParam.bSimulcastAVC = 1;
|
||||
sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
|
||||
sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
|
||||
sParam.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_ROWMB_SLICE;
|
||||
|
||||
sParam.sSpatialLayers[1].iVideoWidth = (iWidth >> 1);
|
||||
sParam.sSpatialLayers[1].iVideoHeight = (iHeight >> 1);
|
||||
sParam.sSpatialLayers[1].sSliceCfg.uiSliceMode = SM_RASTER_SLICE;
|
||||
sParam.sSpatialLayers[1].sSliceCfg.sSliceArgument.uiSliceMbNum[0] = 30;
|
||||
sParam.sSpatialLayers[1].sSliceCfg.sSliceArgument.uiSliceMbNum[1] = 32;
|
||||
|
||||
sParam.sSpatialLayers[2].iVideoWidth = iWidth;
|
||||
sParam.sSpatialLayers[2].iVideoHeight = iHeight;
|
||||
sParam.sSpatialLayers[2].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
||||
sParam.sSpatialLayers[2].sSliceCfg.sSliceArgument.uiSliceNum = (rand() % 30) + 1;
|
||||
|
||||
int rv = encoder_->InitializeExt (&sParam);
|
||||
ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
|
||||
|
||||
unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
|
||||
ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
|
||||
|
||||
int iIdx = 0;
|
||||
|
||||
//create decoder
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
|
||||
EXPECT_TRUE (pBsBuf[iIdx] != NULL);
|
||||
|
||||
long rv = WelsCreateDecoder (&decoder[iIdx]);
|
||||
ASSERT_EQ (0, rv);
|
||||
EXPECT_TRUE (decoder[iIdx] != NULL);
|
||||
|
||||
SDecodingParam decParam;
|
||||
memset (&decParam, 0, sizeof (SDecodingParam));
|
||||
decParam.eOutputColorFormat = videoFormatI420;
|
||||
decParam.uiTargetDqLayer = UCHAR_MAX;
|
||||
decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
|
||||
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
|
||||
|
||||
rv = decoder[iIdx]->Initialize (&decParam);
|
||||
ASSERT_EQ (0, rv);
|
||||
}
|
||||
|
||||
TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
|
||||
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
free (pBsBuf[iIdx]);
|
||||
|
||||
if (decoder[iIdx] != NULL) {
|
||||
decoder[iIdx]->Uninitialize();
|
||||
WelsDestroyDecoder (decoder[iIdx]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F (EncodeDecodeTestAPI, ThreadNumAndSliceNum) {
|
||||
int iSpatialLayerNum = 1;
|
||||
int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
|
||||
int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2),
|
||||
2240);//TODO: use MAX_HEIGHT after the limit is removed
|
||||
float fFrameRate = rand() + 0.5f;
|
||||
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
||||
|
||||
// prepare params
|
||||
SEncParamExt sParam;
|
||||
encoder_->GetDefaultParams (&sParam);
|
||||
prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
|
||||
sParam.iMultipleThreadIdc = (rand() % 3) + 2;
|
||||
sParam.bSimulcastAVC = 1;
|
||||
sParam.sSpatialLayers[0].iVideoWidth = iWidth;
|
||||
sParam.sSpatialLayers[0].iVideoHeight = iHeight;
|
||||
sParam.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
||||
sParam.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = (rand() % 2) ? (sParam.iMultipleThreadIdc + 1) :
|
||||
(sParam.iMultipleThreadIdc - 1);
|
||||
|
||||
int rv = encoder_->InitializeExt (&sParam);
|
||||
ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
|
||||
|
||||
unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
|
||||
ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
|
||||
|
||||
int iIdx = 0;
|
||||
|
||||
//create decoder
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
|
||||
EXPECT_TRUE (pBsBuf[iIdx] != NULL);
|
||||
|
||||
long rv = WelsCreateDecoder (&decoder[iIdx]);
|
||||
ASSERT_EQ (0, rv);
|
||||
EXPECT_TRUE (decoder[iIdx] != NULL);
|
||||
|
||||
SDecodingParam decParam;
|
||||
memset (&decParam, 0, sizeof (SDecodingParam));
|
||||
decParam.eOutputColorFormat = videoFormatI420;
|
||||
decParam.uiTargetDqLayer = UCHAR_MAX;
|
||||
decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
|
||||
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
|
||||
|
||||
rv = decoder[iIdx]->Initialize (&decParam);
|
||||
ASSERT_EQ (0, rv);
|
||||
}
|
||||
|
||||
TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
|
||||
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
free (pBsBuf[iIdx]);
|
||||
|
||||
if (decoder[iIdx] != NULL) {
|
||||
decoder[iIdx]->Uninitialize();
|
||||
WelsDestroyDecoder (decoder[iIdx]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -866,6 +866,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\WelsThreadPoolTest.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
@ -194,3 +194,50 @@ TEST (CWelsCircleQueue, CWelsCircleQueueOnThread) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TEST (CWelsCircleQueue, CWelsCircleQueueReadWithIdx) {
|
||||
CWelsCircleQueue<int32_t> cThreadQueue;
|
||||
const int kiIncreaseNum = (rand() % 1000) + 1;
|
||||
const int kiDecreaseNum = rand() % kiIncreaseNum;
|
||||
|
||||
int32_t* pInput = static_cast<int32_t*> (malloc (kiIncreaseNum * 10 * sizeof (int32_t)));
|
||||
if (!pInput) {
|
||||
return;
|
||||
}
|
||||
for (int32_t i = 0; i < kiIncreaseNum * 10; i++) {
|
||||
pInput[i] = i;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 10; j++) {
|
||||
const int iBias = j * (kiIncreaseNum - kiDecreaseNum);
|
||||
for (int i = 0; i < kiIncreaseNum; i++) {
|
||||
cThreadQueue.push_back (&pInput[i + kiIncreaseNum * j]);
|
||||
}
|
||||
EXPECT_TRUE (kiIncreaseNum + iBias == cThreadQueue.size()) << "after push size=" <<
|
||||
cThreadQueue.size() ;
|
||||
|
||||
EXPECT_TRUE ((kiDecreaseNum * j) == * (cThreadQueue.begin()));
|
||||
|
||||
for (int i = 0; i < kiIncreaseNum; i++) {
|
||||
EXPECT_TRUE ((i + kiIncreaseNum * j) == * (cThreadQueue.GetIndexNode (i + iBias)));
|
||||
}
|
||||
for (int i = 0; i < cThreadQueue.size(); i++) {
|
||||
EXPECT_TRUE ((i + kiDecreaseNum * j) == * (cThreadQueue.GetIndexNode (i)));
|
||||
}
|
||||
|
||||
for (int i = kiDecreaseNum; i > 0; i--) {
|
||||
cThreadQueue.pop_front();
|
||||
}
|
||||
EXPECT_TRUE ((j + 1) * (kiIncreaseNum - kiDecreaseNum) == cThreadQueue.size()) << "after pop size=" <<
|
||||
cThreadQueue.size() ;
|
||||
|
||||
EXPECT_TRUE ((kiDecreaseNum * (j + 1)) == * (cThreadQueue.begin()));
|
||||
}
|
||||
|
||||
//clean-up
|
||||
while (NULL != cThreadQueue.begin()) {
|
||||
cThreadQueue.pop_front();
|
||||
}
|
||||
EXPECT_TRUE (0 == cThreadQueue.size());
|
||||
free (pInput);
|
||||
}
|
||||
|
54
test/common/WelsThreadPoolTest.cpp
Normal file
54
test/common/WelsThreadPoolTest.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "WelsThreadLib.h"
|
||||
#include "WelsThreadPool.h"
|
||||
#include "WelsTask.h"
|
||||
#include "WelsThreadPoolTest.h"
|
||||
|
||||
#define TEST_TASK_NUM 20
|
||||
|
||||
class CSimpleTask : public IWelsTask {
|
||||
public:
|
||||
static uint32_t id;
|
||||
|
||||
CSimpleTask() {
|
||||
m_uiID = id ++;
|
||||
}
|
||||
|
||||
virtual ~CSimpleTask() {
|
||||
}
|
||||
|
||||
virtual int32_t Execute() {
|
||||
WelsSleep (300 - m_uiID);
|
||||
//printf ("Task %d executing\n", m_uiID);
|
||||
return cmResultSuccess;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_uiID;
|
||||
};
|
||||
|
||||
uint32_t CSimpleTask::id = 0;
|
||||
|
||||
|
||||
TEST (CThreadPoolTest, CThreadPoolTest) {
|
||||
CSimpleTask tasks[TEST_TASK_NUM];
|
||||
CThreadPoolTest cThreadPoolTest;
|
||||
CWelsThreadPool cThreadPool (&cThreadPoolTest);
|
||||
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < TEST_TASK_NUM; i++) {
|
||||
cThreadPool.QueueTask (&tasks[i]);
|
||||
}
|
||||
|
||||
while (cThreadPoolTest.GetTaskCount() < TEST_TASK_NUM) {
|
||||
WelsSleep (1);
|
||||
}
|
||||
}
|
||||
|
39
test/common/WelsThreadPoolTest.h
Normal file
39
test/common/WelsThreadPoolTest.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _WELS_THREAD_POOL_TEST_H_
|
||||
#define _WELS_THREAD_POOL_TEST_H_
|
||||
|
||||
#include "WelsThreadPool.h"
|
||||
|
||||
using namespace WelsCommon;
|
||||
|
||||
class CThreadPoolTest : public IWelsThreadPoolSink {
|
||||
public:
|
||||
CThreadPoolTest() {
|
||||
m_iTaskCount = 0;
|
||||
}
|
||||
|
||||
~CThreadPoolTest() {}
|
||||
|
||||
virtual int32_t OnTaskExecuted (IWelsTask* pTask) {
|
||||
m_iTaskCount ++;
|
||||
//printf("Task execute over count is %d\n", m_iTaskCount);
|
||||
return cmResultSuccess;
|
||||
}
|
||||
|
||||
virtual int32_t OnTaskCancelled (IWelsTask* pTask) {
|
||||
m_iTaskCount ++;
|
||||
//printf("Task execute cancelled count is %d\n", m_iTaskCount);
|
||||
return cmResultSuccess;
|
||||
}
|
||||
|
||||
int32_t GetTaskCount() {
|
||||
return m_iTaskCount;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t m_iTaskCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,9 @@
|
||||
COMMON_UNITTEST_SRCDIR=test/common
|
||||
COMMON_UNITTEST_CPP_SRCS=\
|
||||
$(COMMON_UNITTEST_SRCDIR)/ExpandPicture.cpp\
|
||||
$(COMMON_UNITTEST_SRCDIR)/CWelsCircleQueue.cpp\
|
||||
$(COMMON_UNITTEST_SRCDIR)/CWelsListTest.cpp\
|
||||
$(COMMON_UNITTEST_SRCDIR)/ExpandPicture.cpp\
|
||||
$(COMMON_UNITTEST_SRCDIR)/WelsThreadPoolTest.cpp\
|
||||
|
||||
COMMON_UNITTEST_OBJS += $(COMMON_UNITTEST_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user