/*!
 * \copy
 *     Copyright (c)  2009-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.
 *
 *
 *  welsDecoderExt.cpp
 *
 *  Abstract
 *      Cisco OpenH264 decoder extension utilization
 *
 *  History
 *      3/12/2009 Created
 *
 *
 ************************************************************************/
//#include <assert.h>
#include "welsDecoderExt.h"
#include "welsCodecTrace.h"
#include "codec_def.h"
#include "typedefs.h"
#include "memory_align.h"
#include "utils.h"
#include "version.h"

//#include "macros.h"
#include "decoder.h"
#include "decoder_core.h"
#include "manage_dec_ref.h"
#include "error_concealment.h"

#include "measure_time.h"
extern "C" {
#include "decoder_core.h"
#include "manage_dec_ref.h"
}
#include "error_code.h"
#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
#include <time.h>
#if defined(_WIN32) /*&& defined(_DEBUG)*/

#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <malloc.h>
#else
#include <sys/time.h>
#endif

namespace WelsDec {

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/***************************************************************************
*   Description:
*       class CWelsDecoder constructor function, do initialization  and
*       alloc memory required
*
*   Input parameters: none
*
*   return: none
***************************************************************************/
DECLARE_PROCTHREAD (pThrProcInit, p) {
  SWelsDecThreadInfo* sThreadInfo = (SWelsDecThreadInfo*)p;
#if defined(WIN32)
  _alloca (WELS_DEC_MAX_THREAD_STACK_SIZE * (sThreadInfo->uiThrNum + 1));
#endif
  return sThreadInfo->pThrProcMain (p);
}

static DECODING_STATE  ConstructAccessUnit (CWelsDecoder* pWelsDecoder, PWelsDecoderThreadCTX pThrCtx) {
  int iRet = dsErrorFree;
  //WelsMutexLock (&pWelsDecoder->m_csDecoder);
  if (pThrCtx->pCtx->pLastThreadCtx != NULL) {
    PWelsDecoderThreadCTX pLastThreadCtx = (PWelsDecoderThreadCTX) (pThrCtx->pCtx->pLastThreadCtx);
    WAIT_EVENT (&pLastThreadCtx->sSliceDecodeStart, WELS_DEC_THREAD_WAIT_INFINITE);
    RESET_EVENT (&pLastThreadCtx->sSliceDecodeStart);
  }
  pThrCtx->pDec = NULL;
  if (GetThreadCount (pThrCtx->pCtx) > 1) {
    RESET_EVENT (&pThrCtx->sSliceDecodeFinish);
  }
  iRet |= pWelsDecoder->DecodeFrame2WithCtx (pThrCtx->pCtx, NULL, 0, pThrCtx->ppDst, &pThrCtx->sDstInfo);

  //WelsMutexUnlock (&pWelsDecoder->m_csDecoder);
  return (DECODING_STATE)iRet;
}

DECLARE_PROCTHREAD (pThrProcFrame, p) {
  SWelsDecoderThreadCTX* pThrCtx = (SWelsDecoderThreadCTX*)p;
  while (1) {
    RELEASE_SEMAPHORE (pThrCtx->sThreadInfo.sIsBusy);
    RELEASE_SEMAPHORE (&pThrCtx->sThreadInfo.sIsIdle);
    WAIT_SEMAPHORE (&pThrCtx->sThreadInfo.sIsActivated, WELS_DEC_THREAD_WAIT_INFINITE);
    if (pThrCtx->sThreadInfo.uiCommand == WELS_DEC_THREAD_COMMAND_RUN) {
      CWelsDecoder* pWelsDecoder = (CWelsDecoder*)pThrCtx->threadCtxOwner;
      ConstructAccessUnit (pWelsDecoder, pThrCtx);
    } else if (pThrCtx->sThreadInfo.uiCommand == WELS_DEC_THREAD_COMMAND_ABORT) {
      break;
    }
  }
  return 0;
}

CWelsDecoder::CWelsDecoder (void)
  : m_pWelsTrace (NULL),
    m_uiDecodeTimeStamp (0),
    m_bIsBaseline (false),
    m_iCpuCount (1),
    m_iThreadCount (0),
    m_iCtxCount (1),
    m_pPicBuff (NULL),
    m_bParamSetsLostFlag (false),
    m_bFreezeOutput (false),
    m_DecCtxActiveCount (0),
    m_pDecThrCtx (NULL),
    m_pLastDecThrCtx (NULL),
    m_iLastBufferedIdx (0),
    m_iStreamSeqNum (0) {
#ifdef OUTPUT_BIT_STREAM
  char chFileName[1024] = { 0 };  //for .264
  int iBufUsed = 0;
  int iBufLeft = 1023;
  int iCurUsed;

  char chFileNameSize[1024] = { 0 }; //for .len
  int iBufUsedSize = 0;
  int iBufLeftSize = 1023;
  int iCurUsedSize;
#endif//OUTPUT_BIT_STREAM


  m_pWelsTrace = new welsCodecTrace();
  if (m_pWelsTrace != NULL) {
    m_pWelsTrace->SetCodecInstance (this);
    m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);

    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
  }

  ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);

  m_iCpuCount = GetCPUCount();
  if (m_iCpuCount > WELS_DEC_MAX_NUM_CPU) {
    m_iCpuCount = WELS_DEC_MAX_NUM_CPU;
  }

  m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iCtxCount];
  memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iCtxCount);
  for (int32_t i = 0; i < WELS_DEC_MAX_NUM_CPU; ++i) {
    m_pDecThrCtxActive[i] = NULL;
  }
#ifdef OUTPUT_BIT_STREAM
  SWelsTime sCurTime;

  WelsGetTimeOfDay (&sCurTime);

  iCurUsed = WelsSnprintf (chFileName, iBufLeft, "bs_0x%p_", (void*)this);
  iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void*)this);

  iBufUsed += iCurUsed;
  iBufLeft -= iCurUsed;
  if (iBufLeft > 0) {
    iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
    iBufUsed += iCurUsed;
    iBufLeft -= iCurUsed;
  }

  iBufUsedSize += iCurUsedSize;
  iBufLeftSize -= iCurUsedSize;
  if (iBufLeftSize > 0) {
    iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
    iBufUsedSize += iCurUsedSize;
    iBufLeftSize -= iCurUsedSize;
  }

  if (iBufLeft > 0) {
    iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillisecond (&sCurTime));
    iBufUsed += iCurUsed;
    iBufLeft -= iCurUsed;
  }

  if (iBufLeftSize > 0) {
    iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
                                 WelsGetMillisecond (&sCurTime));
    iBufUsedSize += iCurUsedSize;
    iBufLeftSize -= iCurUsedSize;
  }


  m_pFBS = WelsFopen (chFileName, "wb");
  m_pFBSSize = WelsFopen (chFileNameSize, "wb");
#endif//OUTPUT_BIT_STREAM
}

/***************************************************************************
*   Description:
*       class CWelsDecoder destructor function, destroy allocced memory
*
*   Input parameters: none
*
*   return: none
***************************************************************************/
CWelsDecoder::~CWelsDecoder() {
  if (m_pWelsTrace != NULL) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
  }
  CloseDecoderThreads();
  UninitDecoder();

#ifdef OUTPUT_BIT_STREAM
  if (m_pFBS) {
    WelsFclose (m_pFBS);
    m_pFBS = NULL;
  }
  if (m_pFBSSize) {
    WelsFclose (m_pFBSSize);
    m_pFBSSize = NULL;
  }
#endif//OUTPUT_BIT_STREAM

  if (m_pWelsTrace != NULL) {
    delete m_pWelsTrace;
    m_pWelsTrace = NULL;
  }
  if (m_pDecThrCtx != NULL) {
    delete[] m_pDecThrCtx;
    m_pDecThrCtx = NULL;
  }
}

long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
  int iRet = ERR_NONE;
  if (m_pWelsTrace == NULL) {
    return cmMallocMemeError;
  }

  if (pParam == NULL) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsDecoder::Initialize(), invalid input argument.");
    return cmInitParaError;
  }

  // H.264 decoder initialization,including memory allocation,then open it ready to decode
  iRet = InitDecoder (pParam);
  if (iRet)
    return iRet;

  return cmResultSuccess;
}

long CWelsDecoder::Uninitialize() {
  UninitDecoder();

  return ERR_NONE;
}

void CWelsDecoder::UninitDecoder (void) {
  for (int32_t i = 0; i < m_iCtxCount; ++i) {
    if (m_pDecThrCtx[i].pCtx != NULL) {
      if (i > 0) {
        WelsResetRefPicWithoutUnRef (m_pDecThrCtx[i].pCtx);
      }
      UninitDecoderCtx (m_pDecThrCtx[i].pCtx);
    }
  }
}

void CWelsDecoder::OpenDecoderThreads() {
  if (m_iThreadCount >= 1) {
    m_uiDecodeTimeStamp = 0;
    CREATE_SEMAPHORE (&m_sIsBusy, m_iThreadCount, m_iThreadCount, NULL);
    WelsMutexInit (&m_csDecoder);
    CREATE_EVENT (&m_sBufferingEvent, 1, 0, NULL);
    SET_EVENT (&m_sBufferingEvent);
    CREATE_EVENT (&m_sReleaseBufferEvent, 1, 0, NULL);
    SET_EVENT (&m_sReleaseBufferEvent);
    for (int32_t i = 0; i < m_iThreadCount; ++i) {
      m_pDecThrCtx[i].sThreadInfo.uiThrMaxNum = m_iThreadCount;
      m_pDecThrCtx[i].sThreadInfo.uiThrNum = i;
      m_pDecThrCtx[i].sThreadInfo.uiThrStackSize = WELS_DEC_MAX_THREAD_STACK_SIZE;
      m_pDecThrCtx[i].sThreadInfo.pThrProcMain = pThrProcFrame;
      m_pDecThrCtx[i].sThreadInfo.sIsBusy = &m_sIsBusy;
      m_pDecThrCtx[i].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_RUN;
      m_pDecThrCtx[i].threadCtxOwner = this;
      m_pDecThrCtx[i].kpSrc = NULL;
      m_pDecThrCtx[i].kiSrcLen = 0;
      m_pDecThrCtx[i].ppDst = NULL;
      m_pDecThrCtx[i].pDec = NULL;
      CREATE_EVENT (&m_pDecThrCtx[i].sImageReady, 1, 0, NULL);
      CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart, 1, 0, NULL);
      CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinish, 1, 0, NULL);
      CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, 0, 1, NULL);
      CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated, 0, 1, NULL);
      CREATE_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle, pThrProcInit, (void*) (& (m_pDecThrCtx[i])));
    }
  }
}
void CWelsDecoder::CloseDecoderThreads() {
  if (m_iThreadCount >= 1) {
    SET_EVENT (&m_sReleaseBufferEvent);
    for (int32_t i = 0; i < m_iThreadCount; i++) { //waiting the completion begun slices
      WAIT_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
      m_pDecThrCtx[i].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_ABORT;
      RELEASE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated);
      WAIT_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle);
      CLOSE_EVENT (&m_pDecThrCtx[i].sImageReady);
      CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart);
      CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinish);
      CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle);
      CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated);
    }
    WelsMutexDestroy (&m_csDecoder);
    CLOSE_EVENT (&m_sBufferingEvent);
    CLOSE_EVENT (&m_sReleaseBufferEvent);
    CLOSE_SEMAPHORE (&m_sIsBusy);
  }
}

void CWelsDecoder::UninitDecoderCtx (PWelsDecoderContext& pCtx) {
  if (pCtx != NULL) {

    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoderCtx(), openh264 codec version = %s.",
             VERSION_NUMBER);

    WelsEndDecoder (pCtx);

    if (pCtx->pMemAlign != NULL) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
               "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
               pCtx->pMemAlign->WelsGetMemoryUsage());
      delete pCtx->pMemAlign;
      pCtx->pMemAlign = NULL;
    }

    if (NULL != pCtx) {
      WelsFree (pCtx, "m_pDecContext");

      pCtx = NULL;
    }
    if (m_iCtxCount <= 1) m_pDecThrCtx[0].pCtx = NULL;
  }
}

// the return value of this function is not suitable, it need report failure info to upper layer.
int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) {

  WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
           "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
           VERSION_NUMBER, (int32_t)pParam->bParseOnly);
  if (m_iThreadCount >= 1 && pParam->bParseOnly) {
    m_iThreadCount = 0;
  }
  OpenDecoderThreads();
  //reset decoder context
  memset (&m_sDecoderStatistics, 0, sizeof (SDecoderStatistics));
  memset (&m_sLastDecPicInfo, 0, sizeof (SWelsLastDecPicInfo));
  memset (&m_sVlcTable, 0, sizeof (SVlcTable));
  UninitDecoder();
  WelsDecoderLastDecPicInfoDefaults (m_sLastDecPicInfo);
  for (int32_t i = 0; i < m_iCtxCount; ++i) {
    InitDecoderCtx (m_pDecThrCtx[i].pCtx, pParam);
    if (m_iThreadCount >= 1) {
      m_pDecThrCtx[i].pCtx->pThreadCtx = &m_pDecThrCtx[i];
    }
  }
  m_bParamSetsLostFlag = false;
  m_bFreezeOutput = false;
  return cmResultSuccess;
}

// the return value of this function is not suitable, it need report failure info to upper layer.
int32_t CWelsDecoder::InitDecoderCtx (PWelsDecoderContext& pCtx, const SDecodingParam* pParam) {

  WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
           "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
           VERSION_NUMBER, (int32_t)pParam->bParseOnly);

  //reset decoder context
  UninitDecoderCtx (pCtx);
  pCtx = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
  if (NULL == pCtx)
    return cmMallocMemeError;
  int32_t iCacheLineSize = 16;   // on chip cache line size in byte
  pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
  WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pMemAlign), UninitDecoderCtx (pCtx))
  if (m_iCtxCount <= 1) m_pDecThrCtx[0].pCtx = pCtx;
  //fill in default value into context
  pCtx->pLastDecPicInfo = &m_sLastDecPicInfo;
  pCtx->pDecoderStatistics = &m_sDecoderStatistics;
  pCtx->pVlcTable = &m_sVlcTable;
  pCtx->pPictInfoList = m_sPictInfoList;
  pCtx->pPictReoderingStatus = &m_sReoderingStatus;
  pCtx->pCsDecoder = &m_csDecoder;
  pCtx->pStreamSeqNum = &m_iStreamSeqNum;
  WelsDecoderDefaults (pCtx, &m_pWelsTrace->m_sLogCtx);
  WelsDecoderSpsPpsDefaults (pCtx->sSpsPpsCtx);
  //check param and update decoder context
  pCtx->pParam = (SDecodingParam*)pCtx->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
                 "SDecodingParam");
  WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pParam), UninitDecoderCtx (pCtx));
  int32_t iRet = DecoderConfigParam (pCtx, pParam);
  WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);

  //init decoder
  WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (pCtx, &m_pWelsTrace->m_sLogCtx),
                              UninitDecoderCtx (pCtx))
  pCtx->pPicBuff = NULL;
  return cmResultSuccess;
}

int32_t CWelsDecoder::ResetDecoder (PWelsDecoderContext& pCtx) {
  // TBC: need to be modified when context and trace point are null
  if (m_iThreadCount >= 1) {
    ThreadResetDecoder (pCtx);
  } else {
    if (pCtx != NULL && m_pWelsTrace != NULL) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
               pCtx->iErrorCode);
      SDecodingParam sPrevParam;
      memcpy (&sPrevParam, pCtx->pParam, sizeof (SDecodingParam));

      WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoderCtx (pCtx, &sPrevParam),
                                  UninitDecoderCtx (pCtx));
    } else if (m_pWelsTrace != NULL) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
    }
    ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, false);
  }
  return ERR_INFO_UNINIT;
}

int32_t CWelsDecoder::ThreadResetDecoder (PWelsDecoderContext& pCtx) {
  // TBC: need to be modified when context and trace point are null
  SDecodingParam sPrevParam;
  if (pCtx != NULL && m_pWelsTrace != NULL) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d", pCtx->iErrorCode);
    memcpy (&sPrevParam, pCtx->pParam, sizeof (SDecodingParam));
    ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);
    CloseDecoderThreads();
    UninitDecoder();
    InitDecoder (&sPrevParam);
  } else if (m_pWelsTrace != NULL) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
  }
  return ERR_INFO_UNINIT;
}

/*
 * Set Option
 */
long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
  int iVal = 0;
  if (eOptID == DECODER_OPTION_NUM_OF_THREADS) {
    if (pOption != NULL) {
      int32_t threadCount = * ((int32_t*)pOption);
      if (threadCount < 0) threadCount = 0;
      if (threadCount > m_iCpuCount) {
        threadCount = m_iCpuCount;
      }
      if (threadCount > 3) {
        threadCount = 3;
      }
      if (threadCount != m_iThreadCount) {
        m_iThreadCount = threadCount;
        if (m_pDecThrCtx != NULL) {
          delete [] m_pDecThrCtx;
          m_iCtxCount = m_iThreadCount == 0 ? 1 : m_iThreadCount;
          m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iCtxCount];
          memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iCtxCount);
        }
      }
    }
    return cmResultSuccess;
  }
  for (int32_t i = 0; i < m_iCtxCount; ++i) {
    PWelsDecoderContext pDecContext = m_pDecThrCtx[i].pCtx;
    if (pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
        eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
      return dsInitialOptExpected;
    if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
      if (pOption == NULL)
        return cmInitParaError;

      iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag

      if (pDecContext == NULL) return dsInitialOptExpected;

      pDecContext->bEndOfStreamFlag = iVal ? true : false;
      if (iVal && m_iThreadCount >= 1)
        SET_EVENT (&m_sReleaseBufferEvent);

      return cmResultSuccess;
    } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
      if (pOption == NULL)
        return cmInitParaError;

      if (pDecContext == NULL) return dsInitialOptExpected;

      iVal = * ((int*)pOption); // int value for error concealment idc
      iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
      if ((pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
                 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
        return cmInitParaError;
      }

      pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
      InitErrorCon (pDecContext);
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
               "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);

      return cmResultSuccess;
    } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
      if (m_pWelsTrace) {
        uint32_t level = * ((uint32_t*)pOption);
        m_pWelsTrace->SetTraceLevel (level);
      }
      return cmResultSuccess;
    } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
      if (m_pWelsTrace) {
        WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
        m_pWelsTrace->SetTraceCallback (callback);
        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
                 "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
                 callback);
      }
      return cmResultSuccess;
    } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
      if (m_pWelsTrace) {
        void* ctx = * ((void**)pOption);
        m_pWelsTrace->SetTraceCallbackContext (ctx);
      }
      return cmResultSuccess;
    } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
               "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
      return cmInitParaError;
    } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
      if (pOption) {
        if (pDecContext == NULL) return dsInitialOptExpected;
        pDecContext->pDecoderStatistics->iStatisticsLogInterval = (* ((unsigned int*)pOption));
        return cmResultSuccess;
      }
    } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
               "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
      return cmInitParaError;
    }
  }
  return cmInitParaError;
}

/*
 *  Get Option
 */
long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
  int iVal = 0;
  if (DECODER_OPTION_NUM_OF_THREADS == eOptID) {
    * ((int*)pOption) = m_iThreadCount;
    return cmResultSuccess;
  }
  PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
  if (pDecContext == NULL)
    return cmInitExpected;

  if (pOption == NULL)
    return cmInitParaError;

  if (DECODER_OPTION_END_OF_STREAM == eOptID) {
    iVal = pDecContext->bEndOfStreamFlag;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  }
#ifdef LONG_TERM_REF
  else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
    iVal = pDecContext->uiCurIdrPicId;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
    iVal = pDecContext->iFrameNum;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
    iVal = pDecContext->bCurAuContainLtrMarkSeFlag;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
    iVal = pDecContext->iFrameNumOfAuMarkedLtr;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  }
#endif
  else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU
    iVal = pDecContext->iFeedbackVclNalInAu;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID
    iVal = pDecContext->iFeedbackTidInAu;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
    iVal = pDecContext->iFeedbackNalRefIdc;
    if (iVal > 0)
      iVal = 1;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
    iVal = (int)pDecContext->pParam->eEcActiveIdc;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
    SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));

    memcpy (pDecoderStatistics, pDecContext->pDecoderStatistics, sizeof (SDecoderStatistics));

    if (pDecContext->pDecoderStatistics->uiDecodedFrameCount != 0) { //not original status
      pDecoderStatistics->fAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
          (pDecContext->pDecoderStatistics->uiDecodedFrameCount);
      pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
          (pDecContext->pDecoderStatistics->uiDecodedFrameCount + pDecContext->pDecoderStatistics->uiFreezingIDRNum +
           pDecContext->pDecoderStatistics->uiFreezingNonIDRNum);
    }
    return cmResultSuccess;
  } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
    if (pOption) {
      iVal = pDecContext->pDecoderStatistics->iStatisticsLogInterval;
      * ((unsigned int*)pOption) = iVal;
      return cmResultSuccess;
    }
  } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
    PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
    memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
    if (!pDecContext->pSps) {
      return cmInitExpected;
    } else {
      pVuiSarInfo->uiSarWidth = pDecContext->pSps->sVui.uiSarWidth;
      pVuiSarInfo->uiSarHeight = pDecContext->pSps->sVui.uiSarHeight;
      pVuiSarInfo->bOverscanAppropriateFlag = pDecContext->pSps->sVui.bOverscanAppropriateFlag;
      return cmResultSuccess;
    }
  } else if (DECODER_OPTION_PROFILE == eOptID) {
    if (!pDecContext->pSps) {
      return cmInitExpected;
    }
    iVal = (int)pDecContext->pSps->uiProfileIdc;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_LEVEL == eOptID) {
    if (!pDecContext->pSps) {
      return cmInitExpected;
    }
    iVal = (int)pDecContext->pSps->uiLevelIdc;
    * ((int*)pOption) = iVal;
    return cmResultSuccess;
  } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
    for (int32_t activeThread = 0; activeThread < m_DecCtxActiveCount; ++activeThread) {
      WAIT_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
      RELEASE_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle);
    }
    * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts;
    return cmResultSuccess;
  }

  return cmInitParaError;
}

DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,
    const int kiSrcLen,
    unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  int iRet = dsErrorFree;
  if (m_iThreadCount >= 1) {
    SET_EVENT (&m_sReleaseBufferEvent);
    iRet = ThreadDecodeFrameInternal (kpSrc, kiSrcLen, ppDst, pDstInfo);
    if (m_sReoderingStatus.iNumOfPicts) {
      WAIT_EVENT (&m_sBufferingEvent, WELS_DEC_THREAD_WAIT_INFINITE);
      RESET_EVENT (&m_sBufferingEvent);
      RESET_EVENT (&m_sReleaseBufferEvent);
      if (!m_sReoderingStatus.bHasBSlice) {
        if (m_sReoderingStatus.iNumOfPicts > 1) {
          ReleaseBufferedReadyPictureNoReorder (NULL, ppDst, pDstInfo);
        }
      }
      else {
        ReleaseBufferedReadyPictureReorder (NULL, ppDst, pDstInfo);
      }
    }
    return (DECODING_STATE)iRet;
  }
  //SBufferInfo sTmpBufferInfo;
  //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
  iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
  //memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));
  //ppTmpDst[0] = ppDst[0];
  //ppTmpDst[1] = ppDst[1];
  //ppTmpDst[2] = ppDst[2];
  iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);
  //if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {
  //memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));
  //ppDst[0] = ppTmpDst[0];
  //ppDst[1] = ppTmpDst[1];
  //ppDst[2] = ppTmpDst[2];
  //}
  return (DECODING_STATE)iRet;
}

DECODING_STATE CWelsDecoder::DecodeFrame2WithCtx (PWelsDecoderContext pDecContext, const unsigned char* kpSrc,
    const int kiSrcLen,
    unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  if (pDecContext == NULL || pDecContext->pParam == NULL) {
    if (m_pWelsTrace != NULL) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
    }
    return dsInitialOptExpected;
  }

  if (pDecContext->pParam->bParseOnly) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");
    pDecContext->iErrorCode |= dsInvalidArgument;
    return dsInvalidArgument;
  }
  if (CheckBsBuffer (pDecContext, kiSrcLen)) {
    if (ResetDecoder(pDecContext)) {
      if (pDstInfo) pDstInfo->iBufferStatus = 0;
      return dsOutOfMemory;
    }
    return dsErrorFree;
  }
  if (kiSrcLen > 0 && kpSrc != NULL) {
#ifdef OUTPUT_BIT_STREAM
    if (m_pFBS) {
      WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
      WelsFflush (m_pFBS);
    }
    if (m_pFBSSize) {
      WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize);
      WelsFflush (m_pFBSSize);
    }
#endif//OUTPUT_BIT_STREAM
    pDecContext->bEndOfStreamFlag = false;
    if (GetThreadCount (pDecContext) <= 0) {
      pDecContext->uiDecodingTimeStamp = ++m_uiDecodeTimeStamp;
    }
  } else {
    //For application MODE, the error detection should be added for safe.
    //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
    pDecContext->bEndOfStreamFlag = true;
    pDecContext->bInstantDecFlag = true;
  }

  int64_t iStart, iEnd;
  iStart = WelsTime();

  if (GetThreadCount (pDecContext) <= 1) {
    ppDst[0] = ppDst[1] = ppDst[2] = NULL;
  }
  pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
  pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
  unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
  if (GetThreadCount (pDecContext) <= 1) {
    memset (pDstInfo, 0, sizeof (SBufferInfo));
  }
  pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
#ifdef LONG_TERM_REF
  pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
  pDecContext->bCurAuContainLtrMarkSeFlag = false;
  pDecContext->iFrameNumOfAuMarkedLtr = 0;
  pDecContext->iFrameNum = -1; //initialize
#endif

  if (GetThreadCount (pDecContext) >= 1) {
    WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
  }

  pDecContext->iFeedbackTidInAu = -1; //initialize
  pDecContext->iFeedbackNalRefIdc = -1; //initialize
  if (pDstInfo) {
    pDstInfo->uiOutYuvTimeStamp = 0;
    pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
  } else {
    pDecContext->uiTimeStamp = 0;
  }
  WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, ppDst,
                pDstInfo, NULL); //iErrorCode has been modified in this function
  pDecContext->bInstantDecFlag = false; //reset no-delay flag
  if (pDecContext->iErrorCode) {
    EWelsNalUnitType eNalType =
      NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently

    eNalType = pDecContext->sCurNalHead.eNalUnitType;
    if (pDecContext->iErrorCode & dsOutOfMemory) {
      if (ResetDecoder (pDecContext)) {
        if (pDstInfo) pDstInfo->iBufferStatus = 0;
        return dsOutOfMemory;
      }
      return dsErrorFree;
    }
    if (pDecContext->iErrorCode & dsRefListNullPtrs) {
      if (ResetDecoder (pDecContext)) {
        if (pDstInfo) pDstInfo->iBufferStatus = 0;
        return dsRefListNullPtrs;
      }
      return dsErrorFree;
    }
    //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
    if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
        (VIDEO_BITSTREAM_AVC == pDecContext->eVideoType)) {
      if (pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
#ifdef LONG_TERM_REF
        pDecContext->bParamSetsLostFlag = true;
#else
        pDecContext->bReferenceLostAtT0Flag = true;
#endif
      }
    }

    if (pDecContext->bPrintFrameErrorTraceFlag) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
               pDecContext->iErrorCode);
      pDecContext->bPrintFrameErrorTraceFlag = false;
    } else {
      pDecContext->iIgnoredErrorInfoPacketCount++;
      if (pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");
        pDecContext->iIgnoredErrorInfoPacketCount = 0;
      }
    }
    if ((pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
      //TODO after dec status updated
      pDecContext->iErrorCode |= dsDataErrorConcealed;

      pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
      if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
        ResetDecStatNums (pDecContext->pDecoderStatistics);
        pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
      }
      int32_t iMbConcealedNum = pDecContext->iMbEcedNum + pDecContext->iMbEcedPropNum;
      pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->iMbNum == 0 ?
          (pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
                pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
                      iMbConcealedNum * 100) / pDecContext->iMbNum));
      pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->iMbNum == 0 ?
          (pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
                pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
                      pDecContext->iMbEcedPropNum * 100) / pDecContext->iMbNum));
      pDecContext->pDecoderStatistics->uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
      pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
          pDecContext->pDecoderStatistics->uiAvgEcRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
      pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
          pDecContext->pDecoderStatistics->uiAvgEcPropRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
    }
    iEnd = WelsTime();
    pDecContext->dDecTime += (iEnd - iStart) / 1e3;

    OutputStatisticsLog (*pDecContext->pDecoderStatistics);
    if (GetThreadCount (pDecContext) >= 1) {
      BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
      SET_EVENT (&m_sBufferingEvent);
    } else {
      ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
    }

    return (DECODING_STATE)pDecContext->iErrorCode;
  }
  // else Error free, the current codec works well

  if (pDstInfo->iBufferStatus == 1) {

    pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
    if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
      ResetDecStatNums (pDecContext->pDecoderStatistics);
      pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
    }

    OutputStatisticsLog (*pDecContext->pDecoderStatistics);
  }
  iEnd = WelsTime();
  pDecContext->dDecTime += (iEnd - iStart) / 1e3;

  if (GetThreadCount (pDecContext) >= 1) {
    BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
    SET_EVENT (&m_sBufferingEvent);
  } else {
    ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
  }
  return dsErrorFree;
}

DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
    const int kiSrcLen,
    unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
  return DecodeFrame2WithCtx (pDecContext, kpSrc, kiSrcLen, ppDst, pDstInfo);
}

DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  bool bEndOfStreamFlag = true;
  if (m_iThreadCount <= 1) {
    for (int32_t j = 0; j < m_iCtxCount; ++j) {
      if (!m_pDecThrCtx[j].pCtx->bEndOfStreamFlag) {
        bEndOfStreamFlag = false;
      }
    }
  }
  if (bEndOfStreamFlag && m_sReoderingStatus.iNumOfPicts > 0) {
    if (!m_sReoderingStatus.bHasBSlice) {
      ReleaseBufferedReadyPictureNoReorder (NULL, ppDst, pDstInfo);
    }
    else {
      ReleaseBufferedReadyPictureReorder (NULL, ppDst, pDstInfo, true);
    }
  }
  return dsErrorFree;
}

void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {
  if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)
      && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
             "DecoderStatistics: uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \
              uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \
              uiAvgEcRatio=%d, uiAvgEcPropRatio=%d, uiEcIDRNum=%d, uiEcFrameNum=%d, \
              uiIDRLostNum=%d, uiFreezingIDRNum=%d, uiFreezingNonIDRNum=%d, iAvgLumaQp=%d, \
              iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \
              uiProfile=%d, uiLevel=%d, \
              iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",
             sDecoderStatistics.uiWidth,
             sDecoderStatistics.uiHeight,
             sDecoderStatistics.fAverageFrameSpeedInMs,
             sDecoderStatistics.fActualAverageFrameSpeedInMs,

             sDecoderStatistics.uiDecodedFrameCount,
             sDecoderStatistics.uiResolutionChangeTimes,
             sDecoderStatistics.uiIDRCorrectNum,

             sDecoderStatistics.uiAvgEcRatio,
             sDecoderStatistics.uiAvgEcPropRatio,
             sDecoderStatistics.uiEcIDRNum,
             sDecoderStatistics.uiEcFrameNum,

             sDecoderStatistics.uiIDRLostNum,
             sDecoderStatistics.uiFreezingIDRNum,
             sDecoderStatistics.uiFreezingNonIDRNum,
             sDecoderStatistics.iAvgLumaQp,

             sDecoderStatistics.iSpsReportErrorNum,
             sDecoderStatistics.iSubSpsReportErrorNum,
             sDecoderStatistics.iPpsReportErrorNum,
             sDecoderStatistics.iSpsNoExistNalNum,
             sDecoderStatistics.iSubSpsNoExistNalNum,
             sDecoderStatistics.iPpsNoExistNalNum,

             sDecoderStatistics.uiProfile,
             sDecoderStatistics.uiLevel,

             sDecoderStatistics.iCurrentActiveSpsId,
             sDecoderStatistics.iCurrentActivePpsId);
  }
}

void CWelsDecoder::BufferingReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  if (pDstInfo->iBufferStatus == 0) {
    return;
  }
  m_bIsBaseline = pCtx->pSps->uiProfileIdc == 66 || pCtx->pSps->uiProfileIdc == 83;
  if (!m_bIsBaseline) {
    if (pCtx->pSliceHeader->eSliceType == B_SLICE) {
      m_sReoderingStatus.bHasBSlice = true;
    }
  }
  for (int32_t i = 0; i < 16; ++i) {
    if (m_sPictInfoList[i].iPOC == IMinInt32) {
      memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
      m_sPictInfoList[i].iPOC = pCtx->pSliceHeader->iPicOrderCntLsb;
      m_sPictInfoList[i].iSeqNum = pCtx->iSeqNum;
      m_sPictInfoList[i].uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
      if (pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb != NULL) {
        m_sPictInfoList[i].iPicBuffIdx = pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
        if (GetThreadCount (pCtx) <= 1) ++pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iRefCount;
      }
      m_iLastBufferedIdx = i;
      pDstInfo->iBufferStatus = 0;
      ++m_sReoderingStatus.iNumOfPicts;
      if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
        m_sReoderingStatus.iLargestBufferedPicIndex = i;
      }
      break;
    }
  }
}

void CWelsDecoder::ReleaseBufferedReadyPictureReorder (PWelsDecoderContext pCtx, unsigned char** ppDst,
    SBufferInfo* pDstInfo, bool isFlush) {
  PPicBuff pPicBuff = pCtx ? pCtx->pPicBuff : m_pPicBuff;
  if (pCtx == NULL && m_iThreadCount <= 1) {
    pCtx = m_pDecThrCtx[0].pCtx;
  }
  if (m_sReoderingStatus.iNumOfPicts > 0) {
    m_sReoderingStatus.iMinPOC = IMinInt32;
    int32_t firstValidIdx = -1;
    for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
      if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
        m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
        m_sReoderingStatus.iMinSeqNum = m_sPictInfoList[i].iSeqNum;
        m_sReoderingStatus.iPictInfoIndex = i;
        firstValidIdx = i;
        break;
      }
    }
    for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
      if (i == firstValidIdx) continue;
      if (m_sPictInfoList[i].iPOC > IMinInt32
          && ((m_sPictInfoList[i].iSeqNum == m_sReoderingStatus.iMinSeqNum) ? (m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) : (m_sPictInfoList[i].iSeqNum - m_sReoderingStatus.iMinSeqNum < 0))) {
        m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
        m_sReoderingStatus.iMinSeqNum = m_sPictInfoList[i].iSeqNum;
        m_sReoderingStatus.iPictInfoIndex = i;
      }
    }
  }
  if (m_sReoderingStatus.iMinPOC > IMinInt32) {
    bool isReady = true;
    if (!isFlush) {
      int32_t iLastPOC = pCtx != NULL ? pCtx->pSliceHeader->iPicOrderCntLsb : m_sPictInfoList[m_iLastBufferedIdx].iPOC;
      int32_t iLastSeqNum = pCtx != NULL ? pCtx->iSeqNum : m_sPictInfoList[m_iLastBufferedIdx].iSeqNum;
      isReady = (m_sReoderingStatus.iLastWrittenPOC > IMinInt32
        && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
        || m_sReoderingStatus.iMinPOC < iLastPOC
        || m_sReoderingStatus.iMinSeqNum - iLastSeqNum < 0;
    }
    if (isReady) {
      m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
      m_sReoderingStatus.iLastWrittenSeqNum = m_sReoderingStatus.iMinSeqNum;
#if defined (_DEBUG)
#ifdef _MOTION_VECTOR_DUMP_
      fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sReoderingStatus.iLastWrittenPOC,
               m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].uiDecodingTimeStamp);
#endif
#endif
      memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
      ppDst[0] = pDstInfo->pDst[0];
      ppDst[1] = pDstInfo->pDst[1];
      ppDst[2] = pDstInfo->pDst[2];
      m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
      int32_t iPicBuffIdx = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx;
      if (pPicBuff != NULL) {
        if (iPicBuffIdx >= 0 && iPicBuffIdx < pPicBuff->iCapacity)
        {
            PPicture pPic = pPicBuff->ppPic[iPicBuffIdx];
            --pPic->iRefCount;
            if (pPic->iRefCount <= 0 && pPic->pSetUnRef)
              pPic->pSetUnRef(pPic);
        }
      }
      m_sReoderingStatus.iMinPOC = IMinInt32;
      --m_sReoderingStatus.iNumOfPicts;
    }
  }
}

//if there is no b-frame, no ordering based on values of POCs is necessary.
//The function is added to force to avoid picture reordering because some h.264 streams do not follow H.264 POC specifications. 
void CWelsDecoder::ReleaseBufferedReadyPictureNoReorder(PWelsDecoderContext pCtx, unsigned char** ppDst, SBufferInfo* pDstInfo)
{
  int32_t firstValidIdx = -1;
  uint32_t uiDecodingTimeStamp = 0;
  for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
    if (m_sPictInfoList[i].iPOC != IMinInt32) {
      uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
      m_sReoderingStatus.iPictInfoIndex = i;
      firstValidIdx = i;
      break;
    }
  }
  for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
    if (i == firstValidIdx) continue;
    if (m_sPictInfoList[i].iPOC != IMinInt32 && m_sPictInfoList[i].uiDecodingTimeStamp < uiDecodingTimeStamp) {
      uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
      m_sReoderingStatus.iPictInfoIndex = i;
    }
  }
  if (uiDecodingTimeStamp > 0) {
#if defined (_DEBUG)
#ifdef _MOTION_VECTOR_DUMP_
    fprintf(stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC,
      uiDecodingTimeStamp);
#endif
#endif
    m_sReoderingStatus.iLastWrittenPOC = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC;
    m_sReoderingStatus.iLastWrittenSeqNum = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iSeqNum;
    memcpy(pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof(SBufferInfo));
    ppDst[0] = pDstInfo->pDst[0];
    ppDst[1] = pDstInfo->pDst[1];
    ppDst[2] = pDstInfo->pDst[2];
    m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
    if (pCtx || m_pPicBuff) {
      PPicBuff pPicBuff = pCtx ? pCtx->pPicBuff : m_pPicBuff;
      PPicture pPic = pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx];
      --pPic->iRefCount;
      if (pPic->iRefCount <= 0 && pPic->pSetUnRef)
        pPic->pSetUnRef(pPic);
    }
    --m_sReoderingStatus.iNumOfPicts;
  }
  return;
}

DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay(PWelsDecoderContext pDecContext, unsigned char** ppDst,
  SBufferInfo* pDstInfo) {
  DECODING_STATE iRet = dsErrorFree;
  if (pDecContext->pSps != NULL) {
    m_bIsBaseline = pDecContext->pSps->uiProfileIdc == 66 || pDecContext->pSps->uiProfileIdc == 83;
    if (!m_bIsBaseline) {
      if (pDstInfo->iBufferStatus == 1) {
        if (pDecContext->pSliceHeader->eSliceType == B_SLICE &&
            ((pDecContext->iSeqNum == m_sReoderingStatus.iLastWrittenSeqNum) ?
              (pDecContext->pSliceHeader->iPicOrderCntLsb <= m_sReoderingStatus.iLastWrittenPOC + 2) :
              (pDecContext->iSeqNum - m_sReoderingStatus.iLastWrittenSeqNum == 1 && pDecContext->pSliceHeader->iPicOrderCntLsb == 0))) {
          m_sReoderingStatus.iLastWrittenPOC = pDecContext->pSliceHeader->iPicOrderCntLsb;
          m_sReoderingStatus.iLastWrittenSeqNum = pDecContext->iSeqNum;
          //issue #3478, use b-slice type to determine correct picture order as the first priority as POC order is not as reliable as based on b-slice
          ppDst[0] = pDstInfo->pDst[0];
          ppDst[1] = pDstInfo->pDst[1];
          ppDst[2] = pDstInfo->pDst[2];
#if defined (_DEBUG)
#ifdef _MOTION_VECTOR_DUMP_
          fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", pDecContext->pSliceHeader->iPicOrderCntLsb,
             pDecContext->uiDecodingTimeStamp);
#endif
#endif
          return iRet;
        }
        BufferingReadyPicture(pDecContext, ppDst, pDstInfo);
        if (!m_sReoderingStatus.bHasBSlice && m_sReoderingStatus.iNumOfPicts > 1) {
          ReleaseBufferedReadyPictureNoReorder (pDecContext, ppDst, pDstInfo);
        }
        else {
          ReleaseBufferedReadyPictureReorder (pDecContext, ppDst, pDstInfo);
        }
      }
    }
  }
  return iRet;
}

DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, const int kiSrcLen, SParserBsInfo* pDstInfo) {
  PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;

  if (pDecContext == NULL || pDecContext->pParam == NULL) {
    if (m_pWelsTrace != NULL) {
      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
    }
    return dsInitialOptExpected;
  }

  if (!pDecContext->pParam->bParseOnly) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");
    pDecContext->iErrorCode |= dsInvalidArgument;
    return dsInvalidArgument;
  }
  int64_t iEnd, iStart = WelsTime();
  if (CheckBsBuffer (pDecContext, kiSrcLen)) {
    if (ResetDecoder (pDecContext))
      return dsOutOfMemory;

    return dsErrorFree;
  }
  if (kiSrcLen > 0 && kpSrc != NULL) {
#ifdef OUTPUT_BITSTREAM
    if (m_pFBS) {
      WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
      WelsFflush (m_pFBS);
    }
#endif//OUTPUT_BIT_STREAM
    pDecContext->bEndOfStreamFlag = false;
  } else {
    //For application MODE, the error detection should be added for safe.
    //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
    pDecContext->bEndOfStreamFlag = true;
    pDecContext->bInstantDecFlag = true;
  }

  pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
  pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
  pDecContext->iFeedbackNalRefIdc = -1; //initialize
  if (!pDecContext->bFramePending) { //frame complete
    pDecContext->pParserBsInfo->iNalNum = 0;
    memset (pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
  }
  pDstInfo->iNalNum = 0;
  pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
  if (pDstInfo) {
    pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
    pDstInfo->uiOutBsTimeStamp = 0;
  } else {
    pDecContext->uiTimeStamp = 0;
  }
  WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
  if (pDecContext->iErrorCode & dsOutOfMemory) {
    if (ResetDecoder (pDecContext))
      return dsOutOfMemory;
    return dsErrorFree;
  }

  if (!pDecContext->bFramePending && pDecContext->pParserBsInfo->iNalNum) {
    memcpy (pDstInfo, pDecContext->pParserBsInfo, sizeof (SParserBsInfo));

    if (pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
      pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
      if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
        ResetDecStatNums (pDecContext->pDecoderStatistics);
        pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
      }
    }
  }

  pDecContext->bInstantDecFlag = false; //reset no-delay flag

  if (pDecContext->iErrorCode && pDecContext->bPrintFrameErrorTraceFlag) {
    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", pDecContext->iErrorCode);
    pDecContext->bPrintFrameErrorTraceFlag = false;
  }
  iEnd = WelsTime();
  pDecContext->dDecTime += (iEnd - iStart) / 1e3;
  return (DECODING_STATE)pDecContext->iErrorCode;
}

DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
    const int kiSrcLen,
    unsigned char** ppDst,
    int* pStride,
    int& iWidth,
    int& iHeight) {
  DECODING_STATE eDecState = dsErrorFree;
  SBufferInfo    DstInfo;

  memset (&DstInfo, 0, sizeof (SBufferInfo));
  DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];
  DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];
  DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
  DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;

  eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);
  if (eDecState == dsErrorFree) {
    pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
    pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];
    iWidth     = DstInfo.UsrData.sSystemBuffer.iWidth;
    iHeight    = DstInfo.UsrData.sSystemBuffer.iHeight;
  }

  return eDecState;
}

DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc,
    const int kiSrcLen,
    unsigned char* pDst,
    int iDstStride,
    int& iDstLen,
    int& iWidth,
    int& iHeight,
    int& iColorFormat) {
  DECODING_STATE state = dsErrorFree;

  return state;
}

DECODING_STATE CWelsDecoder::ParseAccessUnit (SWelsDecoderThreadCTX& sThreadCtx) {
  sThreadCtx.pCtx->bHasNewSps = false;
  sThreadCtx.pCtx->bParamSetsLostFlag = m_bParamSetsLostFlag;
  sThreadCtx.pCtx->bFreezeOutput = m_bFreezeOutput;
  sThreadCtx.pCtx->uiDecodingTimeStamp = ++m_uiDecodeTimeStamp;
  bool bPicBuffChanged = false;
  if (m_pLastDecThrCtx != NULL && sThreadCtx.pCtx->sSpsPpsCtx.iSeqId < m_pLastDecThrCtx->pCtx->sSpsPpsCtx.iSeqId) {
    CopySpsPps (m_pLastDecThrCtx->pCtx, sThreadCtx.pCtx);
    sThreadCtx.pCtx->iPicQueueNumber = m_pLastDecThrCtx->pCtx->iPicQueueNumber;
    if (sThreadCtx.pCtx->pPicBuff != m_pPicBuff) {
      bPicBuffChanged = true;
      sThreadCtx.pCtx->pPicBuff = m_pPicBuff;
      sThreadCtx.pCtx->bHaveGotMemory = m_pPicBuff != NULL;
      sThreadCtx.pCtx->iImgWidthInPixel = m_pLastDecThrCtx->pCtx->iImgWidthInPixel;
      sThreadCtx.pCtx->iImgHeightInPixel = m_pLastDecThrCtx->pCtx->iImgHeightInPixel;
    }
  }

  //if threadCount > 1, then each thread must contain exact one complete frame.
  if (GetThreadCount (sThreadCtx.pCtx) > 1) {
    sThreadCtx.pCtx->pAccessUnitList->uiAvailUnitsNum = 0;
    sThreadCtx.pCtx->pAccessUnitList->uiActualUnitsNum = 0;
  }

  int32_t iRet = DecodeFrame2WithCtx (sThreadCtx.pCtx, sThreadCtx.kpSrc, sThreadCtx.kiSrcLen, sThreadCtx.ppDst,
                                      &sThreadCtx.sDstInfo);

  int32_t iErr = InitConstructAccessUnit (sThreadCtx.pCtx, &sThreadCtx.sDstInfo);
  if (ERR_NONE != iErr) {
    return (DECODING_STATE) (iRet | iErr);
  }
  if (sThreadCtx.pCtx->bNewSeqBegin) {
    m_pPicBuff = sThreadCtx.pCtx->pPicBuff;
  } else if (bPicBuffChanged) {
    InitialDqLayersContext (sThreadCtx.pCtx, sThreadCtx.pCtx->pSps->iMbWidth << 4, sThreadCtx.pCtx->pSps->iMbHeight << 4);
  }
  if (!sThreadCtx.pCtx->bNewSeqBegin && m_pLastDecThrCtx != NULL) {
    sThreadCtx.pCtx->sFrameCrop = m_pLastDecThrCtx->pCtx->pSps->sFrameCrop;
  }
  m_bParamSetsLostFlag = sThreadCtx.pCtx->bNewSeqBegin ? false : sThreadCtx.pCtx->bParamSetsLostFlag;
  m_bFreezeOutput = sThreadCtx.pCtx->bNewSeqBegin ? false : sThreadCtx.pCtx->bFreezeOutput;
  return (DECODING_STATE)iErr;
}
/*
* Run decoding picture in separate thread.
*/

int CWelsDecoder::ThreadDecodeFrameInternal (const unsigned char* kpSrc, const int kiSrcLen, unsigned char** ppDst,
    SBufferInfo* pDstInfo) {
  int state = dsErrorFree;
  int32_t i, j;
  int32_t signal = 0;

  //serial using of threads
  if (m_DecCtxActiveCount < m_iThreadCount) {
    signal = m_DecCtxActiveCount;
  } else {
    signal = m_pDecThrCtxActive[0]->sThreadInfo.uiThrNum;
  }

  WAIT_SEMAPHORE (&m_pDecThrCtx[signal].sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);

  for (i = 0; i < m_DecCtxActiveCount; ++i) {
    if (m_pDecThrCtxActive[i] == &m_pDecThrCtx[signal]) {
      m_pDecThrCtxActive[i] = NULL;
      for (j = i; j < m_DecCtxActiveCount - 1; j++) {
        m_pDecThrCtxActive[j] = m_pDecThrCtxActive[j + 1];
        m_pDecThrCtxActive[j + 1] = NULL;
      }
      --m_DecCtxActiveCount;
      break;
    }
  }

  m_pDecThrCtxActive[m_DecCtxActiveCount++] = &m_pDecThrCtx[signal];
  if (m_pLastDecThrCtx != NULL) {
    m_pDecThrCtx[signal].pCtx->pLastThreadCtx = m_pLastDecThrCtx;
  }
  m_pDecThrCtx[signal].kpSrc = const_cast<uint8_t*> (kpSrc);
  m_pDecThrCtx[signal].kiSrcLen = kiSrcLen;
  m_pDecThrCtx[signal].ppDst = ppDst;
  memcpy (&m_pDecThrCtx[signal].sDstInfo, pDstInfo, sizeof (SBufferInfo));

  ParseAccessUnit (m_pDecThrCtx[signal]);
  if (m_iThreadCount > 1) {
    m_pLastDecThrCtx = &m_pDecThrCtx[signal];
  }
  m_pDecThrCtx[signal].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_RUN;
  RELEASE_SEMAPHORE (&m_pDecThrCtx[signal].sThreadInfo.sIsActivated);

  // wait early picture
  if (m_DecCtxActiveCount >= m_iThreadCount) {
    WAIT_SEMAPHORE (&m_pDecThrCtxActive[0]->sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
    RELEASE_SEMAPHORE (&m_pDecThrCtxActive[0]->sThreadInfo.sIsIdle);
  }
  return state;
}

} // namespace WelsDec


using namespace WelsDec;
/*
*       WelsGetDecoderCapability
*       @return: DecCapability information
*/
int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {
  memset (pDecCapability, 0, sizeof (SDecoderCapability));
  pDecCapability->iProfileIdc = 66; //Baseline
  pDecCapability->iProfileIop = 0xE0; //11100000b
  pDecCapability->iLevelIdc = 32; //level_idc = 3.2
  pDecCapability->iMaxMbps = 216000; //from level_idc = 3.2
  pDecCapability->iMaxFs = 5120; //from level_idc = 3.2
  pDecCapability->iMaxCpb = 20000; //from level_idc = 3.2
  pDecCapability->iMaxDpb = 20480; //from level_idc = 3.2
  pDecCapability->iMaxBr = 20000; //from level_idc = 3.2
  pDecCapability->bRedPicCap = 0; //not support redundant pic

  return ERR_NONE;
}
/* WINAPI is indeed in prefix due to sync to application layer callings!! */

/*
*   WelsCreateDecoder
*   @return:    success in return 0, otherwise failed.
*/
long WelsCreateDecoder (ISVCDecoder** ppDecoder) {

  if (NULL == ppDecoder) {
    return ERR_INVALID_PARAMETERS;
  }

  *ppDecoder = new CWelsDecoder();

  if (NULL == *ppDecoder) {
    return ERR_MALLOC_FAILED;
  }

  return ERR_NONE;
}

/*
*   WelsDestroyDecoder
*/
void WelsDestroyDecoder (ISVCDecoder* pDecoder) {
  if (NULL != pDecoder) {
    delete (CWelsDecoder*)pDecoder;
  }
}
