shithub: openh264

Download patch

ref: e0cee02d775196bd753a67d98b2f7d710cd35b52
parent: b700b67bbad51bf326ace75954e056e0c8a6c5f4
parent: 819f6f5d93b5c1bd4b08c0b1769f8dc4805bb1fd
author: HaiboZhu <haibozhu@cisco.com>
date: Fri Oct 23 09:21:42 EDT 2015

Merge pull request #2177 from sijchen/thp21

[Encoder] add encoder tasks and task-management class

--- a/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj
+++ b/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj
@@ -7,6 +7,9 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		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 */; };
 		4C23BC60195A77E0003B81FC /* intra_pred_sad_3_opt_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C23BC5F195A77E0003B81FC /* intra_pred_sad_3_opt_aarch64_neon.S */; };
 		4C34066D18C57D0400DFA14A /* intra_pred_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066618C57D0400DFA14A /* intra_pred_neon.S */; };
 		4C34066E18C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066718C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S */; };
@@ -66,6 +69,12 @@
 
 /* Begin PBXFileReference section */
 		04FE0684196FD9370004D7CE /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = version.h; path = ../../../common/inc/version.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>"; };
+		0DD32A9A1B4A49AC009181A1 /* wels_task_management.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wels_task_management.h; sourceTree = "<group>"; };
+		0DD32A9B1B4A4E8F009181A1 /* wels_task_encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wels_task_encoder.cpp; sourceTree = "<group>"; };
+		0DD32A9D1B4A4E9C009181A1 /* wels_task_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wels_task_encoder.h; sourceTree = "<group>"; };
 		4C23BC5F195A77E0003B81FC /* intra_pred_sad_3_opt_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = intra_pred_sad_3_opt_aarch64_neon.S; path = arm64/intra_pred_sad_3_opt_aarch64_neon.S; sourceTree = "<group>"; };
 		4C34066618C57D0400DFA14A /* intra_pred_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_neon.S; sourceTree = "<group>"; };
 		4C34066718C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_sad_3_opt_neon.S; sourceTree = "<group>"; };
@@ -296,6 +305,9 @@
 				4CE446D918BC605C0017DF25 /* wels_const.h */,
 				4CE446DA18BC605C0017DF25 /* wels_func_ptr_def.h */,
 				4CE446DB18BC605C0017DF25 /* wels_preprocess.h */,
+				0DD32A971B4A47D0009181A1 /* wels_task_base.h */,
+				0DD32A9D1B4A4E9C009181A1 /* wels_task_encoder.h */,
+				0DD32A9A1B4A49AC009181A1 /* wels_task_management.h */,
 			);
 			path = inc;
 			sourceTree = "<group>";
@@ -331,6 +343,9 @@
 				4CE446F718BC605C0017DF25 /* svc_motion_estimate.cpp */,
 				4CE446F818BC605C0017DF25 /* svc_set_mb_syn_cavlc.cpp */,
 				4CE446FA18BC605C0017DF25 /* wels_preprocess.cpp */,
+				0DD32A951B4A478B009181A1 /* wels_task_base.cpp */,
+				0DD32A9B1B4A4E8F009181A1 /* wels_task_encoder.cpp */,
+				0DD32A981B4A4997009181A1 /* wels_task_management.cpp */,
 			);
 			path = src;
 			sourceTree = "<group>";
@@ -422,6 +437,7 @@
 				4CE4471018BC605C0017DF25 /* decode_mb_aux.cpp in Sources */,
 				4CE4472018BC605C0017DF25 /* sample.cpp in Sources */,
 				6CA38DA31991CACE003EAAE0 /* svc_motion_estimation.S in Sources */,
+				0DD32A9C1B4A4E8F009181A1 /* wels_task_encoder.cpp in Sources */,
 				4CE4471318BC605C0017DF25 /* encoder_data_tables.cpp in Sources */,
 				4C34067118C57D0400DFA14A /* pixel_neon.S in Sources */,
 				9AED665019469FC1009A3567 /* welsCodecTrace.cpp in Sources */,
@@ -454,8 +470,10 @@
 				4CE4471618BC605C0017DF25 /* get_intra_predictor.cpp in Sources */,
 				4CE4472E18BC605C0017DF25 /* welsEncoderExt.cpp in Sources */,
 				6CA38DA51991D31A003EAAE0 /* svc_motion_estimation_aarch64_neon.S in Sources */,
+				0DD32A991B4A4997009181A1 /* wels_task_management.cpp in Sources */,
 				4CE4471418BC605C0017DF25 /* encoder_ext.cpp in Sources */,
 				4C34067218C57D0400DFA14A /* reconstruct_neon.S in Sources */,
+				0DD32A961B4A478B009181A1 /* wels_task_base.cpp in Sources */,
 				F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
--- a/codec/build/win32/enc/WelsEncCore.vcproj
+++ b/codec/build/win32/enc/WelsEncCore.vcproj
@@ -474,6 +474,18 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\..\encoder\core\src\wels_task_base.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\encoder\core\src\wels_task_encoder.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\encoder\core\src\wels_task_management.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\common\src\WelsTaskThread.cpp"
 				>
 			</File>
--- a/codec/common/inc/WelsTask.h
+++ b/codec/common/inc/WelsTask.h
@@ -29,7 +29,7 @@
  *     POSSIBILITY OF SUCH DAMAGE.
  *
  *
- * \file    WelsThreadPool.h
+ * \file    WelsTask.h
  *
  * \brief   Interfaces introduced in thread pool
  *
@@ -49,7 +49,7 @@
  public:
   virtual ~IWelsTask() { }
 
-  virtual CM_RETURN Execute() = 0;
+  virtual int Execute() = 0;
 };
 
 }
--- a/codec/common/inc/memory_align.h
+++ b/codec/common/inc/memory_align.h
@@ -104,6 +104,12 @@
 
 #define WELS_SAFE_FREE(pPtr, pTag)              if (pPtr) { WelsFree(pPtr, pTag); pPtr = NULL; }
 
+#define  WELS_NEW_OP(object, type)   \
+  (type*)(new object);
+
+#define  WELS_DELETE_OP(p) \
+  delete p;            \
+  p = NULL;
 
 }
 
--- a/codec/common/src/WelsThreadLib.cpp
+++ b/codec/common/src/WelsThreadLib.cpp
@@ -302,7 +302,7 @@
   if (p_event == NULL) {
     return WELS_THREAD_ERROR_GENERAL;
   }
-  char    strSuffix[16] = { 0 };
+  char    strSuffix[100] = { 0 };
   if (NULL == event_name) {
     sprintf (strSuffix, "WelsSem%ld_p%ld", (intptr_t)p_event, (long) (getpid()));
     event_name = &strSuffix[0];
@@ -341,6 +341,10 @@
 #endif
 }
 
+void WelsSleep (uint32_t dwMilliSecond) {
+  usleep (dwMilliSecond * 1000);
+}
+
 WELS_THREAD_ERROR_CODE   WelsEventSignal (WELS_EVENT* event) {
   WELS_THREAD_ERROR_CODE err = 0;
 //  int32_t val = 0;
@@ -354,10 +358,6 @@
 
 WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) {
   return sem_wait (*event); // blocking until signaled
-}
-
-void WelsSleep (uint32_t dwMilliSecond) {
-  usleep (dwMilliSecond * 1000);
 }
 
 WELS_THREAD_ERROR_CODE    WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -60,6 +60,7 @@
 
 namespace WelsEnc {
 
+class IWelsTaskManage;
 /*
  *  reference list for each quality layer in SVC
  */
@@ -133,6 +134,7 @@
   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
 
 // SSlice context
   SSliceCtx*        pSliceCtxList;// slice context table for each dependency quality layer
--- a/codec/encoder/core/inc/mt_defs.h
+++ b/codec/encoder/core/inc/mt_defs.h
@@ -88,6 +88,8 @@
 #endif//MT_DEBUG
 
 uint8_t*                        pThreadBsBuffer[MAX_THREADS_NUM]; //actual memory for slice buffer
+bool                            bThreadBsBufferUsage[MAX_THREADS_NUM];
+WELS_MUTEX                      mutexThreadBsBufferUsage;
 } SSliceThreading;
 
 #endif//MULTIPLE_THREADING_DEFINES_H__
--- a/codec/encoder/core/inc/slice_multi_threading.h
+++ b/codec/encoder/core/inc/slice_multi_threading.h
@@ -99,6 +99,11 @@
 #endif//defined(MT_DEBUG)
 
 void SetOneSliceBsBufferUnderMultithread(sWelsEncCtx* pCtx, const int32_t kiThreadIdx, const int32_t iSliceIdx);
+int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pDst,
+                        int32_t* pNalLen,
+                        int32_t iTotalLeftLength,
+                        const int32_t iSliceIdx,
+                        int32_t& iSliceSize);
 }
 
 #endif//SVC_SLICE_MULTIPLE_THREADING_H__
--- a/codec/encoder/core/inc/wels_common_basis.h
+++ b/codec/encoder/core/inc/wels_common_basis.h
@@ -45,6 +45,7 @@
 
 namespace WelsEnc {
 
+typedef int32_t WelsErrorType;
 
 struct SMVUnitXY { // each 4 Bytes
   int16_t iMvX;
--- /dev/null
+++ b/codec/encoder/core/inc/wels_task_base.h
@@ -1,0 +1,75 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_base.h
+ *
+ * \brief   interface for base task
+ *
+ * \date    5/09/2012 Created
+ *
+ *************************************************************************************
+ */
+
+
+
+#ifndef  _WELS_BASE_TASK_H_
+#define  _WELS_BASE_TASK_H_
+
+#include "typedefs.h"
+#include "WelsTask.h"
+
+namespace WelsEnc {
+
+class CWelsBaseTask : public WelsCommon::IWelsTask {
+ public:
+  enum {
+    WELS_ENC_TASK_ENCODE_FIXED_SLICE = 0,
+    WELS_ENC_TASK_ENCODE_SLICE_LOADBALANCING = 1,
+    WELS_ENC_TASK_ENCODE_SLICE_SIZECONSTRAINED = 2,
+  };
+
+  CWelsBaseTask();
+  virtual ~CWelsBaseTask();
+
+  virtual uint32_t GetTaskType() const = 0;
+
+ private:
+
+};
+
+}
+
+
+#endif
+
+
+
+
--- /dev/null
+++ b/codec/encoder/core/inc/wels_task_encoder.h
@@ -1,0 +1,127 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_encoder.h
+ *
+ * \brief   interface for encoder tasks
+ *
+ * \date    07/06/2015 Created
+ *
+ *************************************************************************************
+ */
+
+#ifndef _WELS_ENCODER_TASK_H_
+#define _WELS_ENCODER_TASK_H_
+
+#include "wels_task_base.h"
+#include "encoder_context.h"
+
+namespace WelsEnc {
+
+extern int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer,
+                                    const int32_t iSliceIdx,
+                                    int32_t& iSliceSize);
+extern int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSliceIdx, int32_t& iSliceSize);
+
+class CWelsSliceEncodingTask : public CWelsBaseTask {
+ public:
+  CWelsSliceEncodingTask (sWelsEncCtx* pCtx, const int32_t iSliceIdx);
+  virtual ~CWelsSliceEncodingTask();
+
+  CWelsSliceEncodingTask* CreateSliceEncodingTask (sWelsEncCtx* pCtx, const int32_t iSliceIdx);
+  WelsErrorType SetBoundary (int32_t iStartMbIdx, int32_t iEndMbIdx);
+
+  virtual WelsErrorType Execute();
+  virtual WelsErrorType InitTask();
+  virtual void FinishTask();
+
+  virtual uint32_t        GetTaskType() const {
+    return WELS_ENC_TASK_ENCODE_FIXED_SLICE;
+  }
+ protected:
+  int32_t QueryEmptyThread (bool* pThreadBsBufferUsage);
+
+  sWelsEncCtx* m_pCtx;
+  SSliceThreadPrivateData* m_pPrivateData;
+  SLayerBSInfo* m_pLbi;
+  int32_t m_iStartMbIdx;
+  int32_t m_iEndMbIdx;
+
+  EWelsNalUnitType m_eNalType;
+  EWelsNalRefIdc m_eNalRefIdc;
+  bool m_bNeedPrefix;
+  uint32_t m_uiDependencyId;
+
+  SSlice* m_pSlice;
+  SWelsSliceBs* m_pSliceBs;
+  int32_t m_iSliceIdx;
+  int32_t m_iSliceSize;
+  int32_t m_iThreadIdx;
+};
+
+class CWelsLoadBalancingSlicingEncodingTask : public CWelsSliceEncodingTask {
+ public:
+  CWelsLoadBalancingSlicingEncodingTask (sWelsEncCtx* pCtx, const int32_t iSliceIdx);
+  ~CWelsLoadBalancingSlicingEncodingTask();
+
+  virtual WelsErrorType InitTask();
+  virtual void FinishTask();
+
+  virtual uint32_t        GetTaskType() const {
+    return WELS_ENC_TASK_ENCODE_SLICE_LOADBALANCING;
+  }
+ private:
+  int64_t m_iSliceStart;
+};
+
+/*
+class CWelsConstrainedSizeSlicingEncodingTask : public CWelsSliceEncodingTask {
+ public:
+  CWelsConstrainedSizeSlicingEncodingTask (sWelsEncCtx* pCtx);
+  ~CWelsConstrainedSizeSlicingEncodingTask();
+
+  virtual WelsErrorType Execute();
+
+  WelsErrorType InitTask ();
+  virtual void FinishTask();
+
+  virtual uint32_t        GetTaskType() const {
+    return WELS_ENC_TASK_ENCODE_SLICE_SIZECONSTRAINED;
+  }
+ protected:
+
+};
+*/
+
+
+}       //namespace
+#endif  //header guard
+
--- /dev/null
+++ b/codec/encoder/core/inc/wels_task_management.h
@@ -1,0 +1,128 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_management.h
+ *
+ * \brief   interface for task management
+ *
+ * \date    5/14/2012 Created
+ *
+ *************************************************************************************
+ */
+
+#ifndef _WELS_ENCODER_TASK_MANAGE_H_
+#define _WELS_ENCODER_TASK_MANAGE_H_
+
+#include "wels_common_basis.h"
+#include "WelsLock.h"
+#include "WelsThreadPool.h"
+
+namespace WelsEnc {
+
+class CWelsBaseTask;
+
+class IWelsTaskManage {
+ public:
+  virtual ~IWelsTaskManage() { }
+
+  virtual WelsErrorType   Init (sWelsEncCtx*   pEncCtx) = 0;
+  virtual void            Uninit() = 0;
+
+  virtual void            InitFrame() {}
+  virtual WelsErrorType   ExecuteTasks() = 0;
+
+  static IWelsTaskManage* CreateTaskManage (sWelsEncCtx* pCtx, bool bNeedLock);
+};
+
+
+class  CWelsTaskManageBase : public IWelsTaskManage, public WelsCommon::IWelsThreadPoolSink {
+ public:
+  typedef  CWelsCircleQueue<CWelsBaseTask>            TASKLIST_TYPE;
+  //typedef  std::pair<int, int>                  SLICE_BOUNDARY_PAIR;
+  //typedef  CWelsCircleQueue<SLICE_BOUNDARY_PAIR>       SLICE_PAIR_LIST;
+
+  CWelsTaskManageBase();
+  virtual ~ CWelsTaskManageBase();
+
+  virtual WelsErrorType   Init (sWelsEncCtx*   pEncCtx);
+  void    Uninit();
+
+  virtual void            InitFrame();
+  virtual WelsErrorType   ExecuteTasks();
+
+  //IWelsThreadPoolSink
+  virtual WelsErrorType  OnTaskExecuted (WelsCommon::IWelsTask* pTask);
+  virtual WelsErrorType  OnTaskCancelled (WelsCommon::IWelsTask* pTask);
+
+ protected:
+  virtual  WelsErrorType  CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount);
+  void                    DestroyTasks();
+
+ protected:
+  sWelsEncCtx*    m_pEncCtx;
+
+  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;
+  WELS_EVENT       m_hTaskEvent;
+
+  WelsCommon::CWelsLock  m_cWaitTaskNumLock;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN (CWelsTaskManageBase);
+};
+
+class  CWelsTaskManageOne : public CWelsTaskManageBase {
+ public:
+  CWelsTaskManageOne();
+  virtual ~CWelsTaskManageOne();
+
+  WelsErrorType   Init (sWelsEncCtx* pEncCtx);
+  virtual WelsErrorType  ExecuteTasks();
+};
+
+class  CWelsTaskManageParallel : public CWelsTaskManageBase {
+ public:
+  virtual WelsErrorType  ExecuteTasks();
+
+ protected:
+  virtual  WelsErrorType  CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount);
+};
+
+}       //namespace
+#endif  //header guard
+
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -62,6 +62,7 @@
 #include "cpu.h"
 
 #include "measure_time.h"
+#include "wels_task_management.h"
 
 #if defined(ENABLE_TRACE_MT)
 #define MT_TRACE_LOG(x, ...) WelsLog(x, __VA_ARGS__)
@@ -443,6 +444,10 @@
   iReturn = WelsMutexInit (&pSmt->mutexSliceNumUpdate);
   WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), 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))
+
   iReturn = WelsMutexInit (& (*ppCtx)->mutexEncoderError);
   WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
 
@@ -496,6 +501,7 @@
   WelsEventClose (&pSmt->pSliceCodedMasterEvent, ename);
 
   WelsMutexDestroy (&pSmt->mutexSliceNumUpdate);
+  WelsMutexDestroy (&pSmt->mutexThreadBsBufferUsage);
   WelsMutexDestroy (& ((*ppCtx)->mutexEncoderError));
 
   if (pSmt->pThreadPEncCtx != NULL) {
@@ -509,6 +515,7 @@
       pSmt->pThreadBsBuffer[i] = NULL;
     }
   }
+  memset(&pSmt->bThreadBsBufferUsage, 0, MAX_THREADS_NUM * sizeof(bool));
 
   pSliceB = (*ppCtx)->pSliceBs;
   iIdx = 0;
--- /dev/null
+++ b/codec/encoder/core/src/wels_task_base.cpp
@@ -1,0 +1,55 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_base.cpp
+ *
+ * \brief   function for base task
+ *
+ * \date    5/09/2012 Created
+ *
+ *************************************************************************************
+ */
+
+#include "wels_task_base.h"
+
+namespace WelsEnc {
+
+CWelsBaseTask::CWelsBaseTask() {
+}
+
+CWelsBaseTask::~CWelsBaseTask() {
+}
+
+
+}
+
+
+
--- /dev/null
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -1,0 +1,208 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_encoder.h
+ *
+ * \brief   interface for encoder tasks
+ *
+ * \date    07/06/2015 Created
+ *
+ *************************************************************************************
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "typedefs.h"
+#include "utils.h"
+#include "measure_time.h"
+#include "WelsTask.h"
+
+#include "wels_task_base.h"
+#include "wels_task_encoder.h"
+
+#include "svc_enc_golomb.h"
+#include "svc_encode_slice.h"
+#include "slice_multi_threading.h"
+
+namespace WelsEnc {
+
+CWelsSliceEncodingTask::CWelsSliceEncodingTask (sWelsEncCtx* pCtx, const int32_t iSliceIdx) {
+  m_pCtx = pCtx;
+  m_iSliceIdx = iSliceIdx;
+}
+
+CWelsSliceEncodingTask::~CWelsSliceEncodingTask() {
+}
+
+WelsErrorType CWelsSliceEncodingTask::SetBoundary (int32_t iStartIdx,  int32_t iEndIdx) {
+  m_iStartMbIdx = iStartIdx;
+  m_iEndMbIdx = iEndIdx;
+  return ENC_RETURN_SUCCESS;
+}
+
+int32_t CWelsSliceEncodingTask::QueryEmptyThread (bool* pThreadBsBufferUsage) {
+  for (int32_t k = 0; k < MAX_THREADS_NUM; k++) {
+    if (pThreadBsBufferUsage[k] == false) {
+      pThreadBsBufferUsage[k] = true;
+      return k;
+    }
+  }
+  return -1;
+}
+
+WelsErrorType CWelsSliceEncodingTask::InitTask() {
+  m_eNalType          = m_pCtx->eNalType;
+  m_eNalRefIdc        = m_pCtx->eNalPriority;
+  m_bNeedPrefix       = m_pCtx->bNeedPrefixNalFlag;
+
+  WelsMutexLock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);
+  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);
+    return ENC_RETURN_UNEXPECTED;
+  }
+  SetOneSliceBsBufferUnderMultithread (m_pCtx, m_iSliceIdx, m_iThreadIdx);
+
+  m_pSlice = &m_pCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[m_iSliceIdx];
+  m_pSliceBs = &m_pCtx->pSliceBs[m_iSliceIdx];
+
+  m_pSliceBs->uiBsPos       = 0;
+  m_pSliceBs->iNalIndex     = 0;
+
+  assert ((void*) (&m_pSliceBs->sBsWrite) == (void*)m_pSlice->pSliceBsa);
+  InitBits (&m_pSliceBs->sBsWrite, m_pSliceBs->pBsBuffer, m_pSliceBs->uiSize);
+
+  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");
+
+#if MT_DEBUG_BS_WR
+  m_pSliceBs->bSliceCodedFlag = false;
+#endif//MT_DEBUG_BS_WR
+
+  if (m_bNeedPrefix) {
+    if (m_eNalRefIdc != NRI_PRI_LOWEST) {
+      WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc);
+      WelsWriteSVCPrefixNal (&m_pSliceBs->sBsWrite, m_eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == m_eNalType));
+      WelsUnloadNalForSlice (m_pSliceBs);
+    } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension
+      WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc);
+      // No need write any syntax of prefix NAL Unit RBSP here
+      WelsUnloadNalForSlice (m_pSliceBs);
+    }
+  }
+
+  WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc);
+  int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_iSliceIdx, m_eNalType);
+  if (ENC_RETURN_SUCCESS != iReturn) {
+    return iReturn;
+  }
+  WelsUnloadNalForSlice (m_pSliceBs);
+
+  m_iSliceSize = 0;
+  int32_t iLeftBufferSize = (m_iSliceIdx > 0) ? (m_pSliceBs->uiSize - (int32_t) (m_pSliceBs->sBsWrite.pCurBuf -
+                            m_pSliceBs->sBsWrite.pStartBuf)) : (m_pCtx->iFrameBsSize - m_pCtx->iPosBsBuffer);
+  iReturn = WriteSliceBs (m_pCtx, m_pSliceBs->pBs,
+                          &m_pSliceBs->iNalLen[0],
+                          iLeftBufferSize,
+                          m_iSliceIdx, m_iSliceSize);
+  if (ENC_RETURN_SUCCESS != iReturn) {
+    return iReturn;
+  }
+  if (0 == m_iSliceIdx) {
+    m_pCtx->iPosBsBuffer += m_iSliceSize;
+  }
+
+  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
+
+#if MT_DEBUG_BS_WR
+  m_pSliceBs->bSliceCodedFlag = true;
+#endif//MT_DEBUG_BS_WR
+
+  return ENC_RETURN_SUCCESS;
+}
+
+
+// CWelsLoadBalancingSlicingEncodingTask
+CWelsLoadBalancingSlicingEncodingTask::CWelsLoadBalancingSlicingEncodingTask (sWelsEncCtx* pCtx,
+    const int32_t iSliceIdx) :
+  CWelsSliceEncodingTask (pCtx, iSliceIdx) {
+}
+
+CWelsLoadBalancingSlicingEncodingTask::~CWelsLoadBalancingSlicingEncodingTask() {
+}
+
+WelsErrorType CWelsLoadBalancingSlicingEncodingTask::InitTask() {
+  WelsErrorType iReturn = CWelsSliceEncodingTask::InitTask();
+  if (ENC_RETURN_SUCCESS != iReturn) {
+    return iReturn;
+  }
+
+  m_iSliceStart = WelsTime();
+  return ENC_RETURN_SUCCESS;
+}
+
+void CWelsLoadBalancingSlicingEncodingTask::FinishTask() {
+  CWelsSliceEncodingTask::FinishTask();
+
+  m_pCtx->pSliceThreading->pSliceConsumeTime[m_uiDependencyId][m_iSliceIdx] = (uint32_t) (WelsTime() - m_iSliceStart);
+  WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
+           "[MT] CodingSliceThreadProc(), coding_idx %d, um_iSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, pFirstMbInSlice %d, count_num_mb_in_slice %d",
+           m_pCtx->iCodingIndex,
+           m_iSliceIdx,
+           m_pCtx->pSliceThreading->pSliceConsumeTime[m_uiDependencyId][m_iSliceIdx],
+           m_iSliceSize,
+           m_pCtx->pCurDqLayer->pSliceEncCtx->pFirstMbInSlice[m_iSliceIdx],
+           m_pCtx->pCurDqLayer->pSliceEncCtx->pCountMbNumInSlice[m_iSliceIdx]);
+}
+
+}
+
+
--- /dev/null
+++ b/codec/encoder/core/src/wels_task_management.cpp
@@ -1,0 +1,213 @@
+/*!
+ * \copy
+ *     Copyright (c)  2009-2015, 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.
+ *
+ *
+ * \file    wels_task_management.cpp
+ *
+ * \brief   function for task management
+ *
+ * \date    5/14/2012 Created
+ *
+ *************************************************************************************
+ */
+#include <string.h>
+#include <assert.h>
+
+#include "typedefs.h"
+#include "WelsLock.h"
+#include "memory_align.h"
+
+#include "wels_common_basis.h"
+#include "encoder_context.h"
+#include "wels_task_base.h"
+#include "wels_task_encoder.h"
+#include "wels_task_management.h"
+
+namespace WelsEnc {
+
+
+
+IWelsTaskManage*   IWelsTaskManage::CreateTaskManage (sWelsEncCtx* pCtx, bool bNeedLock) {
+  if (NULL == pCtx) {
+    return NULL;
+  }
+  IWelsTaskManage* pTaskManage;
+  if (bNeedLock) {
+    pTaskManage = WELS_NEW_OP (CWelsTaskManageParallel(), CWelsTaskManageParallel);
+  } else {
+    pTaskManage = WELS_NEW_OP (CWelsTaskManageBase(), CWelsTaskManageBase);
+  }
+
+  if (pTaskManage) {
+    pTaskManage->Init (pCtx);
+  }
+  return pTaskManage;
+}
+
+
+CWelsTaskManageBase::CWelsTaskManageBase()
+  : m_pEncCtx (NULL),
+    m_iTaskNum (0),
+    m_pThreadPool (NULL),
+    m_iWaitTaskNum (0) {
+  m_cTaskList = new TASKLIST_TYPE();
+  WelsEventOpen (&m_hTaskEvent);
+}
+
+CWelsTaskManageBase::~CWelsTaskManageBase() {
+  //printf("~CWelsTaskManageBase\n");
+  Uninit();
+}
+
+WelsErrorType CWelsTaskManageBase::Init (sWelsEncCtx* pEncCtx) {
+  m_pEncCtx = pEncCtx;
+
+  m_iThreadNum = m_pEncCtx->pSvcParam->iMultipleThreadIdc;
+  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);
+  return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount);
+}
+
+void   CWelsTaskManageBase::Uninit() {
+  DestroyTasks();
+  WELS_DELETE_OP (m_pThreadPool);
+
+  delete m_cTaskList;
+  WelsEventClose (&m_hTaskEvent);
+}
+
+WelsErrorType CWelsTaskManageBase::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount) {
+  CWelsBaseTask* pTask = NULL;
+
+  for (int idx = 0; idx < kiTaskCount; idx++) {
+    pTask = WELS_NEW_OP (CWelsSliceEncodingTask (pEncCtx, idx), CWelsSliceEncodingTask);
+    WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask)
+    m_cTaskList->push_back (pTask);
+  }
+  m_iTaskNum = 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;
+
+  if (m_cTaskList->size() != m_iTaskNum) {
+    //printf("m_cTaskList %d %d\n", static_cast<int32_t>(m_cTaskList->size()), m_iTaskNum);
+    //WELS_ERROR_TRACE ("CWelsTaskManage::DestroyTasks:  Incorrect task numbers");
+  }
+
+  while (NULL != m_cTaskList->begin()) {
+    CWelsBaseTask* pTask = m_cTaskList->begin();
+    WELS_DELETE_OP (pTask);
+    m_cTaskList->pop_front();
+  }
+  m_iTaskNum = 0;
+}
+
+void CWelsTaskManageBase::InitFrame() {
+}
+
+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);
+
+  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 ");
+  }
+
+  return ENC_RETURN_SUCCESS;
+}
+
+WelsErrorType  CWelsTaskManageBase::OnTaskCancelled (WelsCommon::IWelsTask* pTask) {
+  WelsCommon::CWelsAutoLock cAutoLock (m_cWaitTaskNumLock);
+  m_iWaitTaskNum --;
+  if (m_iWaitTaskNum == 0) {
+    WelsEventSignal (&m_hTaskEvent);
+  }
+  return ENC_RETURN_SUCCESS;
+}
+
+WelsErrorType CWelsTaskManageOne::Init (sWelsEncCtx* pEncCtx) {
+  Uninit();
+  m_pEncCtx = pEncCtx;
+
+  return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount);
+}
+
+WelsErrorType  CWelsTaskManageOne::ExecuteTasks() {
+  while (NULL != m_cTaskList->begin()) {
+    (m_cTaskList->begin())->Execute();
+    m_cTaskList->pop_front();
+  }
+  return ENC_RETURN_SUCCESS;
+}
+
+//TODO: at present there is no diff betweenCWelsTaskManageParallel and CWelsTaskManageBase, to finish later
+WelsErrorType  CWelsTaskManageParallel::ExecuteTasks() {
+  WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool)
+
+  // need lock here?
+  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);
+
+  return ENC_RETURN_SUCCESS;
+}
+
+WelsErrorType   CWelsTaskManageParallel::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount) {
+  return ENC_RETURN_SUCCESS;
+}
+
+}
+
+
+
+
--- a/codec/encoder/targets.mk
+++ b/codec/encoder/targets.mk
@@ -27,6 +27,9 @@
 	$(ENCODER_SRCDIR)/core/src/svc_set_mb_syn_cabac.cpp\
 	$(ENCODER_SRCDIR)/core/src/svc_set_mb_syn_cavlc.cpp\
 	$(ENCODER_SRCDIR)/core/src/wels_preprocess.cpp\
+	$(ENCODER_SRCDIR)/core/src/wels_task_base.cpp\
+	$(ENCODER_SRCDIR)/core/src/wels_task_encoder.cpp\
+	$(ENCODER_SRCDIR)/core/src/wels_task_management.cpp\
 	$(ENCODER_SRCDIR)/plus/src/welsEncoderExt.cpp\
 
 ENCODER_OBJS += $(ENCODER_CPP_SRCS:.cpp=.$(OBJ))
--- /dev/null
+++ b/test/encoder/EncUT_EncoderTaskManagement.cpp
@@ -1,0 +1,34 @@
+#include <gtest/gtest.h>
+
+#include "utils/DataGenerator.h"
+#include "encoder_context.h"
+#include "wels_task_management.h"
+
+using namespace WelsEnc;
+
+
+TEST (EncoderTaskManagement, CWelsTaskManageBase) {
+  sWelsEncCtx sCtx;
+  SWelsSvcCodingParam sWelsSvcCodingParam;
+
+  sCtx.pSvcParam = &sWelsSvcCodingParam;
+  sWelsSvcCodingParam.iMultipleThreadIdc = 4;
+  sCtx.iMaxSliceCount = 35;
+  IWelsTaskManage*  pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, false);
+  ASSERT_TRUE (NULL != pTaskManage);
+
+  delete pTaskManage;
+}
+
+TEST (EncoderTaskManagement, CWelsTaskManageParallel) {
+  sWelsEncCtx sCtx;
+  SWelsSvcCodingParam sWelsSvcCodingParam;
+
+  sCtx.pSvcParam = &sWelsSvcCodingParam;
+  sWelsSvcCodingParam.iMultipleThreadIdc = 4;
+  sCtx.iMaxSliceCount = 35;
+  IWelsTaskManage*  pTaskManage = IWelsTaskManage::CreateTaskManage (&sCtx, true);
+  ASSERT_TRUE (NULL != pTaskManage);
+
+  delete pTaskManage;
+}
\ No newline at end of file
--- a/test/encoder/targets.mk
+++ b/test/encoder/targets.mk
@@ -4,6 +4,7 @@
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_EncoderExt.cpp\
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_EncoderMb.cpp\
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_EncoderMbAux.cpp\
+	$(ENCODER_UNITTEST_SRCDIR)/EncUT_EncoderTaskManagement.cpp\
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_ExpGolomb.cpp\
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_GetIntraPredictor.cpp\
 	$(ENCODER_UNITTEST_SRCDIR)/EncUT_InterfaceTest.cpp\