ref: aeb5ab4b9981cb346d075755f2d1eee440979fd8
parent: beacba76e33841be0b26013a735081a8b8f54407
author: sijchen <sijchen@cisco.com>
date: Wed Nov 11 17:55:16 EST 2015
[Encoder] put the logic related to multiple D layer into a class for better structure
--- a/codec/encoder/core/inc/wels_task_management.h
+++ b/codec/encoder/core/inc/wels_task_management.h
@@ -58,7 +58,7 @@
virtual void InitFrame (const int32_t kiCurDid) {}
virtual WelsErrorType ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType = CWelsBaseTask::WELS_ENC_TASK_ENCODING) = 0;
- static IWelsTaskManage* CreateTaskManage (sWelsEncCtx* pCtx, bool bNeedLock);
+ static IWelsTaskManage* CreateTaskManage (sWelsEncCtx* pCtx, const int32_t iSpatialLayer, const bool bNeedLock);
};
@@ -71,11 +71,10 @@
CWelsTaskManageBase();
virtual ~ CWelsTaskManageBase();
- virtual WelsErrorType Init (sWelsEncCtx* pEncCtx);
- void Uninit();
+ virtual WelsErrorType Init (sWelsEncCtx* pEncCtx);
+ virtual void InitFrame (const int32_t kiCurDid = 0);
- virtual void InitFrame (const int32_t kiCurDid);
- virtual WelsErrorType ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType = CWelsBaseTask::WELS_ENC_TASK_ENCODING);
+ virtual WelsErrorType ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType = CWelsBaseTask::WELS_ENC_TASK_ENCODING);
//IWelsThreadPoolSink
virtual WelsErrorType OnTaskExecuted (WelsCommon::IWelsTask* pTask);
@@ -82,18 +81,19 @@
virtual WelsErrorType OnTaskCancelled (WelsCommon::IWelsTask* pTask);
protected:
- virtual WelsErrorType CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount);
- void DestroyTasks();
- WelsErrorType ExecuteTaskList(TASKLIST_TYPE* pTargetTaskList);
+ virtual WelsErrorType CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount);
+ WelsErrorType ExecuteTaskList(TASKLIST_TYPE* pTargetTaskList);
+
protected:
sWelsEncCtx* m_pEncCtx;
WelsCommon::CWelsThreadPool* m_pThreadPool;
- TASKLIST_TYPE* m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_ALL];
- TASKLIST_TYPE* m_cEncodingTaskList;
- TASKLIST_TYPE* m_cPreEncodingTaskList;
- int32_t m_iTaskNum;
+ TASKLIST_TYPE* m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_ALL];
+ TASKLIST_TYPE* m_cEncodingTaskList;
+ TASKLIST_TYPE* m_cPreEncodingTaskList;
+ int32_t m_iCurrentTaskNum;
+ int32_t m_iTotalTaskNum;
//SLICE_PAIR_LIST *m_cSliceList;
@@ -107,6 +107,10 @@
private:
DISALLOW_COPY_AND_ASSIGN (CWelsTaskManageBase);
void OnTaskMinusOne();
+
+ void Uninit();
+ void DestroyTasks();
+ void DestroyTaskList(TASKLIST_TYPE* pTargetTaskList);
};
class CWelsTaskManageOne : public CWelsTaskManageBase {
@@ -116,6 +120,17 @@
WelsErrorType Init (sWelsEncCtx* pEncCtx);
virtual WelsErrorType ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType = CWelsBaseTask::WELS_ENC_TASK_ENCODING);
+};
+
+class CWelsTaskManageMultiD : public CWelsTaskManageBase {
+public:
+ virtual WelsErrorType Init (sWelsEncCtx* pEncCtx);
+ virtual void InitFrame (const int32_t kiCurDid);
+ virtual WelsErrorType ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType = CWelsBaseTask::WELS_ENC_TASK_ENCODING);
+
+private:
+ int32_t m_iTaskNumD[MAX_DEPENDENCY_LAYER];
+ int32_t m_iCurDid;
};
class CWelsTaskManageParallel : public CWelsTaskManageBase {
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -452,7 +452,7 @@
WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
if (bWillUseTaskManage) {
- (*ppCtx)->pTaskManage = IWelsTaskManage::CreateTaskManage(*ppCtx, bDynamicSlice);
+ (*ppCtx)->pTaskManage = IWelsTaskManage::CreateTaskManage(*ppCtx, iNumSpatialLayers, bDynamicSlice);
WELS_VERIFY_RETURN_PROC_IF (iReturn, (NULL == (*ppCtx)->pTaskManage), FreeMemorySvc (ppCtx))
}
--- a/codec/encoder/core/src/wels_task_management.cpp
+++ b/codec/encoder/core/src/wels_task_management.cpp
@@ -55,14 +55,15 @@
-IWelsTaskManage* IWelsTaskManage::CreateTaskManage (sWelsEncCtx* pCtx, bool bNeedLock) {
+IWelsTaskManage* IWelsTaskManage::CreateTaskManage (sWelsEncCtx* pCtx, const int32_t iSpatialLayer,
+ const bool bNeedLock) {
if (NULL == pCtx) {
return NULL;
}
IWelsTaskManage* pTaskManage;
- if (bNeedLock) {
- pTaskManage = WELS_NEW_OP (CWelsTaskManageParallel(), CWelsTaskManageParallel);
+ if (iSpatialLayer > 1) {
+ pTaskManage = WELS_NEW_OP (CWelsTaskManageMultiD(), CWelsTaskManageMultiD);
} else {
pTaskManage = WELS_NEW_OP (CWelsTaskManageBase(), CWelsTaskManageBase);
}
@@ -77,7 +78,7 @@
CWelsTaskManageBase::CWelsTaskManageBase()
: m_pEncCtx (NULL),
m_pThreadPool (NULL),
- m_iTaskNum (0),
+ m_iTotalTaskNum (0),
m_iWaitTaskNum (0) {
m_cEncodingTaskList = new TASKLIST_TYPE();
m_cPreEncodingTaskList = new TASKLIST_TYPE();
@@ -85,7 +86,7 @@
}
CWelsTaskManageBase::~CWelsTaskManageBase() {
- //printf("~CWelsTaskManageBase\n");
+ //printf ("~CWelsTaskManageBase\n");
Uninit();
}
@@ -96,11 +97,12 @@
m_pThreadPool = WELS_NEW_OP (WelsCommon::CWelsThreadPool (this, m_iThreadNum),
WelsCommon::CWelsThreadPool);
WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool)
- //printf("CWelsTaskManageBase Init m_iThreadNum %d pEncCtx->iMaxSliceCount=%d\n", m_iThreadNum, pEncCtx->iMaxSliceCount);
m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_ENCODING] = m_cEncodingTaskList;
m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_PREENCODING] = m_cPreEncodingTaskList;
+ m_iCurrentTaskNum = pEncCtx->pSvcParam->sSpatialLayers[0].sSliceArgument.uiSliceNum;
+ //printf ("CWelsTaskManageBase Init m_iThreadNum %d m_iCurrentTaskNum %d pEncCtx->iMaxSliceCount %d\n", m_iThreadNum, m_iCurrentTaskNum, pEncCtx->iMaxSliceCount);
return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount);
}
@@ -127,31 +129,34 @@
WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask)
m_cEncodingTaskList->push_back (pTask);
}
- m_iTaskNum = kiTaskCount;
+ m_iTotalTaskNum = kiTaskCount;
- //printf("CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount);
+ //printf ("CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount);
return ENC_RETURN_SUCCESS;
}
-void CWelsTaskManageBase::DestroyTasks() {
- if (m_iTaskNum == 0) {
- return;
+void CWelsTaskManageBase::DestroyTaskList (TASKLIST_TYPE* pTargetTaskList) {
+ if (pTargetTaskList->size() != m_iTotalTaskNum) {
+ printf ("pTargetTaskList size=%d m_iTotalTaskNum=%d\n", static_cast<int32_t> (pTargetTaskList->size()),
+ m_iTotalTaskNum);
}
-
- if (m_cEncodingTaskList->size() != m_iTaskNum) {
- //printf("m_cEncodingTaskList %d %d\n", static_cast<int32_t>(m_cEncodingTaskList->size()), m_iTaskNum);
- //WELS_ERROR_TRACE ("CWelsTaskManage::DestroyTasks: Incorrect task numbers");
+ //printf ("CWelsTaskManageBase: pTargetTaskList size=%d m_iTotalTaskNum=%d\n", static_cast<int32_t> (pTargetTaskList->size()), m_iTotalTaskNum);
+ while (NULL != pTargetTaskList->begin()) {
+ CWelsBaseTask* pTask = pTargetTaskList->begin();
+ WELS_DELETE_OP (pTask);
+ pTargetTaskList->pop_front();
}
+}
- while (NULL != m_cEncodingTaskList->begin()) {
- CWelsBaseTask* pTask = m_cEncodingTaskList->begin();
- WELS_DELETE_OP (pTask);
- m_cEncodingTaskList->pop_front();
+void CWelsTaskManageBase::DestroyTasks() {
+ if (m_iTotalTaskNum == 0) {
+ return;
}
- //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;
+
+ DestroyTaskList (m_cEncodingTaskList);
+ DestroyTaskList (m_cPreEncodingTaskList);
+ //printf ("[MT] CWelsTaskManageBase() DestroyTasks, cleaned %d tasks\n", m_iTotalTaskNum);
+ m_iTotalTaskNum = 0;
}
void CWelsTaskManageBase::OnTaskMinusOne() {
@@ -159,8 +164,9 @@
m_iWaitTaskNum --;
if (m_iWaitTaskNum <= 0) {
WelsEventSignal (&m_hTaskEvent);
+ //printf ("OnTaskMinusOne WelsEventSignal m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
}
- //printf("OnTaskMinusOne m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
+ //printf ("OnTaskMinusOne m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
}
WelsErrorType CWelsTaskManageBase::OnTaskCancelled (WelsCommon::IWelsTask* pTask) {
@@ -173,18 +179,17 @@
return ENC_RETURN_SUCCESS;
}
-void CWelsTaskManageBase::InitFrame (const int32_t kiCurDid) {
- m_iWaitTaskNum = m_pEncCtx->pSvcParam->sSpatialLayers[kiCurDid].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::ExecuteTaskList (TASKLIST_TYPE* pTargetTaskList) {
+ m_iWaitTaskNum = m_iCurrentTaskNum;
+ //printf ("ExecuteTaskList m_iWaitTaskNum=%d\n", m_iWaitTaskNum);
+ if (0 == m_iWaitTaskNum) {
+ return ENC_RETURN_SUCCESS;
+ }
-WelsErrorType CWelsTaskManageBase::ExecuteTaskList(TASKLIST_TYPE* pTargetTaskList) {
- //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 (pTargetTaskList->GetIndexNode(iIdx));
+ m_pThreadPool->QueueTask (pTargetTaskList->GetIndexNode (iIdx));
iIdx ++;
}
WelsEventWait (&m_hTaskEvent);
@@ -192,27 +197,45 @@
return ENC_RETURN_SUCCESS;
}
-WelsErrorType CWelsTaskManageBase::ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType) {
- return ExecuteTaskList(m_pcAllTaskList[iTaskType]);
+void CWelsTaskManageBase::InitFrame (const int32_t kiCurDid) {
+ ExecuteTaskList (m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_PREENCODING]);
}
-WelsErrorType CWelsTaskManageOne::Init (sWelsEncCtx* pEncCtx) {
- Uninit();
- m_pEncCtx = pEncCtx;
-
- return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount);
+WelsErrorType CWelsTaskManageBase::ExecuteTasks (const CWelsBaseTask::ETaskType iTaskType) {
+ return ExecuteTaskList (m_pcAllTaskList[iTaskType]);
}
-WelsErrorType CWelsTaskManageOne::ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType) {
- while (NULL != m_cEncodingTaskList->begin()) {
- (m_cEncodingTaskList->begin())->Execute();
- m_cEncodingTaskList->pop_front();
+WelsErrorType CWelsTaskManageMultiD::Init (sWelsEncCtx* pEncCtx) {
+ WelsErrorType ret = CWelsTaskManageBase::Init (pEncCtx);
+
+ //TODO: the iMaxTaskNum logic here is for protection for now, may remove later
+ int32_t iMaxTaskNum = 0;
+ for (int32_t i = 0; i < m_pEncCtx->pSvcParam->iSpatialLayerNum; i++) {
+ m_iTaskNumD[i] = m_pEncCtx->pSvcParam->sSpatialLayers[i].sSliceArgument.uiSliceNum;
+ iMaxTaskNum = WELS_MAX (m_iTaskNumD[i], iMaxTaskNum);
}
- return ENC_RETURN_SUCCESS;
+ //printf("CWelsTaskManageMultiD::Init, m_iTotalTaskNum=%d, iMaxTaskNum=%d\n", m_iTotalTaskNum, iMaxTaskNum);
+ assert(m_iTotalTaskNum==iMaxTaskNum);
+ //
+
+ return ret;
}
+void CWelsTaskManageMultiD::InitFrame (const int32_t kiCurDid) {
+ //printf("CWelsTaskManageMultiD: InitFrame: m_iCurDid=%d, m_iCurrentTaskNum=%d\n", m_iCurDid, m_iCurrentTaskNum);
+ m_iCurDid = kiCurDid;
+ m_iCurrentTaskNum = m_iTaskNumD[kiCurDid];
+ ExecuteTaskList (m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_PREENCODING]);
+}
+
+WelsErrorType CWelsTaskManageMultiD::ExecuteTasks (const CWelsBaseTask::ETaskType iTaskType) {
+ m_iCurrentTaskNum = m_iTaskNumD[m_iCurDid];
+ return CWelsTaskManageBase::ExecuteTasks (iTaskType);
+}
+
+
//TODO: at present there is no diff betweenCWelsTaskManageParallel and CWelsTaskManageBase, to finish later
-WelsErrorType CWelsTaskManageParallel::ExecuteTasks(const CWelsBaseTask::ETaskType iTaskType) {
+WelsErrorType CWelsTaskManageParallel::ExecuteTasks (const CWelsBaseTask::ETaskType iTaskType) {
WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool)
// need lock here?
@@ -230,6 +253,22 @@
WelsErrorType CWelsTaskManageParallel::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount) {
return ENC_RETURN_SUCCESS;
}
+
+// CWelsTaskManageOne is for test
+WelsErrorType CWelsTaskManageOne::Init (sWelsEncCtx* pEncCtx) {
+ m_pEncCtx = pEncCtx;
+
+ return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount);
+}
+
+WelsErrorType CWelsTaskManageOne::ExecuteTasks (const CWelsBaseTask::ETaskType iTaskType) {
+ while (NULL != m_cEncodingTaskList->begin()) {
+ (m_cEncodingTaskList->begin())->Execute();
+ m_cEncodingTaskList->pop_front();
+ }
+ return ENC_RETURN_SUCCESS;
+}
+// CWelsTaskManageOne is for test
}
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -536,7 +536,7 @@
pSpatialCfg->sSliceArgument.uiSliceSizeConstraint,
pSpatialCfg->uiProfileIdc,
pSpatialCfg->uiLevelIdc
- );
+ );
++ i;
}
}
--- a/test/encoder/EncUT_EncoderTaskManagement.cpp
+++ b/test/encoder/EncUT_EncoderTaskManagement.cpp
@@ -14,7 +14,7 @@
sCtx.pSvcParam = &sWelsSvcCodingParam;
sWelsSvcCodingParam.iMultipleThreadIdc = 4;
sCtx.iMaxSliceCount = 35;
- IWelsTaskManage* pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, false);
+ IWelsTaskManage* pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, 1, false);
ASSERT_TRUE (NULL != pTaskManage);
delete pTaskManage;
@@ -27,7 +27,22 @@
sCtx.pSvcParam = &sWelsSvcCodingParam;
sWelsSvcCodingParam.iMultipleThreadIdc = 4;
sCtx.iMaxSliceCount = 35;
- IWelsTaskManage* pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, true);
+ IWelsTaskManage* pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, 1, true);
+ ASSERT_TRUE (NULL != pTaskManage);
+
+ delete pTaskManage;
+}
+
+TEST (EncoderTaskManagement, CWelsTaskManageMultiD) {
+ sWelsEncCtx sCtx;
+ SWelsSvcCodingParam sWelsSvcCodingParam;
+
+ sCtx.pSvcParam = &sWelsSvcCodingParam;
+ sWelsSvcCodingParam.iMultipleThreadIdc = 4;
+ sWelsSvcCodingParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = 35;
+ sCtx.iMaxSliceCount = 35;
+
+ IWelsTaskManage* pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, 4, true);
ASSERT_TRUE (NULL != pTaskManage);
delete pTaskManage;