shithub: openh264

Download patch

ref: f911895dbbbcaab72749d281e7a865151e8a7e46
parent: d52c64a2a56ce6de6055d8908b0b9d8f4c3018cc
parent: 3d532fff80597d355cb9939623447ed709425bed
author: ruil2 <ruil2@cisco.com>
date: Wed Sep 28 10:09:49 EDT 2016

Merge pull request #2565 from ycqian/fixListQueue

fix CWelsList CWelsCircleQueue issue

--- a/codec/common/inc/WelsCircleQueue.h
+++ b/codec/common/inc/WelsCircleQueue.h
@@ -52,12 +52,13 @@
  public:
   CWelsCircleQueue() {
     m_iMaxNodeCount = 50;
-    m_pCurrentQueue = static_cast<TNodeType**> (malloc (m_iMaxNodeCount * sizeof (TNodeType*)));
+    m_pCurrentQueue = NULL;
     //here using array to simulate list is to avoid the frequent malloc/free of Nodes which may cause fragmented memory
     m_iCurrentListStart = m_iCurrentListEnd = 0;
   };
   ~CWelsCircleQueue() {
-    free (m_pCurrentQueue);
+    if (m_pCurrentQueue)
+      free (m_pCurrentQueue);
   };
 
   int32_t size() {
@@ -67,6 +68,12 @@
   }
 
   int32_t push_back (TNodeType* pNode) {
+    if (NULL == m_pCurrentQueue) {
+      m_pCurrentQueue = static_cast<TNodeType**> (malloc (m_iMaxNodeCount * sizeof (TNodeType*)));
+      if (NULL == m_pCurrentQueue)
+        return 1;
+    }
+
     if ((NULL != pNode) && (find (pNode))) {      //not checking NULL for easier testing
       return 1;
     }
--- a/codec/common/inc/WelsList.h
+++ b/codec/common/inc/WelsList.h
@@ -59,12 +59,15 @@
   CWelsList() {
     m_iCurrentNodeCount = 0;
     m_iMaxNodeCount = 50;
-    m_pCurrentList = static_cast<SNode<TNodeType>*> (malloc (m_iMaxNodeCount * sizeof (SNode<TNodeType>)));
-    //here using array storage to simulate list is to avoid the frequent malloc/free of Nodes which may cause fragmented memory
-    ResetStorage();
+
+    m_pCurrentList = NULL;
+    m_pFirst = NULL;
+    m_pCurrent = NULL;
+    m_pLast = NULL;
   };
   ~CWelsList() {
-    free (m_pCurrentList);
+    if (m_pCurrentList)
+      free (m_pCurrentList);
   };
 
   int32_t size() {
@@ -72,22 +75,24 @@
   }
 
   bool push_back (TNodeType* pNode) {
-    m_pCurrent->pPointer = pNode;
-    if (0 == m_iCurrentNodeCount) {
-      m_pFirst = m_pCurrent;
+    if (NULL == m_pCurrentList) {
+      m_pCurrentList = static_cast<SNode<TNodeType>*> (malloc (m_iMaxNodeCount * sizeof (SNode<TNodeType>)));
+      if (NULL == m_pCurrentList) {
+        return false;
+      } else {
+        ResetStorage();
+      }
     }
 
-    m_iCurrentNodeCount++;
-    if (m_iCurrentNodeCount == m_iMaxNodeCount) {
+    if (NULL == m_pCurrent) {
       if (!ExpandList()) {
         return false;
       }
     }
 
-    SNode<TNodeType>* pNext = FindNextStorage();
-    m_pCurrent->pNextNode = pNext;
-    pNext->pPrevNode = m_pCurrent;
-    m_pCurrent = pNext;
+    m_pCurrent->pPointer = pNode;
+    m_pCurrent = m_pCurrent->pNextNode;
+    m_iCurrentNodeCount++;
 
     return true;
   }
@@ -105,18 +110,20 @@
     }
 
     SNode<TNodeType>* pTemp = m_pFirst;
-    if (m_iCurrentNodeCount > 0) {
-      m_iCurrentNodeCount --;
-    }
 
-    if (0 == m_iCurrentNodeCount) {
-      ResetStorage();
-    } else {
-      m_pFirst = m_pFirst->pNextNode;
-      m_pFirst->pPrevNode = NULL;
+    m_pFirst = m_pFirst->pNextNode;
+    m_pFirst->pPrevNode = NULL;
 
-      CleanOneNode (pTemp);
-    }
+    CleanOneNode (pTemp);
+
+    m_pLast->pNextNode = pTemp;
+    pTemp->pPrevNode = m_pLast;
+    m_pLast = pTemp;
+
+    if (NULL == m_pCurrent)
+      m_pCurrent = m_pLast;
+
+    m_iCurrentNodeCount --;
   }
 
   bool erase (TNodeType* pNode) {
@@ -139,15 +146,17 @@
 
         CleanOneNode (pTemp);
         m_iCurrentNodeCount --;
+
+        m_pLast->pNextNode = pTemp;
+        pTemp->pPrevNode = m_pLast;
+        m_pLast = pTemp;
+
         return true;
       }
 
-      if (pTemp->pNextNode) {
-        pTemp = pTemp->pNextNode;
-      } else {
-        break;
-      }
-    } while (pTemp->pPointer && pTemp->pNextNode);
+      pTemp = pTemp->pNextNode;
+
+    } while (pTemp && pTemp->pPointer);
     return false;
   }
 
@@ -170,8 +179,9 @@
     m_pCurrentList = tmpCurrentList;
     m_iCurrentNodeCount = m_iMaxNodeCount;
     m_iMaxNodeCount = m_iMaxNodeCount * 2;
-    m_pFirst = m_pCurrentList;
-    m_pCurrent = & (m_pCurrentList[m_iCurrentNodeCount - 1]);
+    m_pFirst = & (m_pCurrentList[0]);
+    m_pLast = & (m_pCurrentList[m_iMaxNodeCount - 1]);
+    m_pCurrent = & (m_pCurrentList[m_iCurrentNodeCount]);
     return true;
   }
 
@@ -189,22 +199,7 @@
     pList[iMaxIndex].pNextNode = NULL;
   }
 
-  SNode<TNodeType>* FindNextStorage() {
 
-    if (NULL != m_pCurrent->pNextNode) {
-      if (NULL == m_pCurrent->pNextNode->pPointer) {
-        return (m_pCurrent->pNextNode);
-      }
-    }
-
-    for (int32_t i = 0; i < m_iMaxNodeCount; i++) {
-      if (NULL == m_pCurrentList[i].pPointer) {
-        return (&m_pCurrentList[i]);
-      }
-    }
-    return NULL;
-  }
-
   void CleanOneNode (SNode<TNodeType>* pSNode) {
     pSNode->pPointer = NULL;
     pSNode->pPrevNode = NULL;
@@ -212,9 +207,10 @@
   }
 
   void ResetStorage() {
-    m_pFirst = NULL;
-    m_pCurrent = m_pCurrentList;
     InitStorage (m_pCurrentList, m_iMaxNodeCount - 1);
+    m_pCurrent = m_pCurrentList;
+    m_pFirst = & (m_pCurrentList[0]);
+    m_pLast = & (m_pCurrentList[m_iMaxNodeCount - 1]);
   }
 
   int32_t m_iCurrentNodeCount;
@@ -221,6 +217,7 @@
   int32_t m_iMaxNodeCount;
   SNode<TNodeType>* m_pCurrentList;
   SNode<TNodeType>* m_pFirst;
+  SNode<TNodeType>* m_pLast;
   SNode<TNodeType>* m_pCurrent;
 };
 
--- a/codec/common/inc/WelsThreadPool.h
+++ b/codec/common/inc/WelsThreadPool.h
@@ -86,7 +86,7 @@
   WELS_THREAD_ERROR_CODE AddThreadToIdleQueue (CWelsTaskThread* pThread);
   WELS_THREAD_ERROR_CODE AddThreadToBusyList (CWelsTaskThread* pThread);
   WELS_THREAD_ERROR_CODE RemoveThreadFromBusyList (CWelsTaskThread* pThread);
-  void           AddTaskToWaitedList (IWelsTask* pTask);
+  bool           AddTaskToWaitedList (IWelsTask* pTask);
   CWelsTaskThread*   GetIdleThread();
   IWelsTask*         GetWaitedTask();
   int32_t            GetIdleThreadNum();
--- a/codec/common/inc/memory_align.h
+++ b/codec/common/inc/memory_align.h
@@ -108,7 +108,7 @@
   (type*)(new object);
 
 #define  WELS_DELETE_OP(p) \
-  delete p;            \
+  if(p) delete p;            \
   p = NULL;
 
 }
--- a/codec/common/src/WelsThreadPool.cpp
+++ b/codec/common/src/WelsThreadPool.cpp
@@ -234,7 +234,9 @@
     }
   }
   //fprintf(stdout, "ThreadPool:  AddTaskToWaitedList: %x\n", pTask);
-  AddTaskToWaitedList (pTask);
+  if (false == AddTaskToWaitedList (pTask)){
+      return WELS_THREAD_ERROR_GENERAL;
+  }
 
   //fprintf(stdout, "ThreadPool:  SignalThread: %x\n", pTask);
   SignalThread();
@@ -285,12 +287,12 @@
   }
 }
 
-void  CWelsThreadPool::AddTaskToWaitedList (IWelsTask* pTask) {
+bool  CWelsThreadPool::AddTaskToWaitedList (IWelsTask* pTask) {
   CWelsAutoLock  cLock (m_cLockWaitedTasks);
 
-  m_cWaitedTasks->push_back (pTask);
+  int32_t nRet = m_cWaitedTasks->push_back (pTask);
   //fprintf(stdout, "CWelsThreadPool::AddTaskToWaitedList=%d, pTask=%x\n", m_cWaitedTasks->size(), pTask);
-  return;
+  return (0==nRet ? true : false);
 }
 
 CWelsTaskThread*   CWelsThreadPool::GetIdleThread() {
--- a/codec/encoder/core/src/wels_task_management.cpp
+++ b/codec/encoder/core/src/wels_task_management.cpp
@@ -149,7 +149,7 @@
   for (int idx = 0; idx < kiTaskCount; idx++) {
     pTask = WELS_NEW_OP (CWelsUpdateMbMapTask (this, pEncCtx, idx), CWelsUpdateMbMapTask);
     WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask)
-    m_cPreEncodingTaskList[kiCurDid]->push_back (pTask);
+    WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, 0 != m_cPreEncodingTaskList[kiCurDid]->push_back (pTask));
   }
 
   for (int idx = 0; idx < kiTaskCount; idx++) {
@@ -164,7 +164,7 @@
       }
     }
     WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask)
-    m_cEncodingTaskList[kiCurDid]->push_back (pTask);
+    WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, 0 != m_cEncodingTaskList[kiCurDid]->push_back (pTask) );
   }
 
   //fprintf(stdout, "CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount);