Guangwei Wangastyle code style for enc3d150f09 years agoHistory
341 lines · 13.4 KB · C++
RawDownload
/*! * \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 (WelsCommon::IWelsTaskSink* pSink, sWelsEncCtx* pCtx,    const int32_t iSliceIdx) : CWelsBaseTask (pSink), m_eTaskResult (ENC_RETURN_SUCCESS) {  m_pCtx = pCtx;  m_iSliceIdx = iSliceIdx;} CWelsSliceEncodingTask::~CWelsSliceEncodingTask() {} WelsErrorType CWelsSliceEncodingTask::Execute() {  //fprintf(stdout, "OpenH264Enc_CWelsSliceEncodingTask_Execute, %x, sink=%x\n", this, m_pSink);   m_eTaskResult = InitTask();  WELS_VERIFY_RETURN_IFNEQ (m_eTaskResult, ENC_RETURN_SUCCESS)   m_eTaskResult = ExecuteTask();   FinishTask();   //fprintf(stdout, "OpenH264Enc_CWelsSliceEncodingTask_Execute Ends\n");  return m_eTaskResult;} 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);   WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,           "[MT] CWelsSliceEncodingTask()InitTask for m_iSliceIdx %d, lock thread %d",           m_iSliceIdx, m_iThreadIdx);  if (m_iThreadIdx < 0) {    WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,             "[MT] CWelsSliceEncodingTask InitTask(), Cannot find available thread for m_iSliceIdx = %d", m_iSliceIdx);    return ENC_RETURN_UNEXPECTED;  }   int32_t iReturn = InitOneSliceInThread (m_pCtx, m_pSlice, m_iThreadIdx, m_pCtx->uiDependencyId, m_iSliceIdx);  WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)  m_pSliceBs = &m_pSlice->sSliceBs;   iReturn   = SetSliceBoundaryInfo (m_pCtx->pCurDqLayer, m_pSlice, m_iSliceIdx);  WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)   SetOneSliceBsBufferUnderMultithread (m_pCtx, m_iThreadIdx, m_pSlice);   assert ((void*) (&m_pSliceBs->sBsWrite) == (void*)m_pSlice->pSliceBsa);  InitBits (&m_pSliceBs->sBsWrite, m_pSliceBs->pBsBuffer, m_pSliceBs->uiSize);  //printf ("CWelsSliceEncodingTask_InitTask slice %d\n", m_iSliceIdx);   return ENC_RETURN_SUCCESS;} void CWelsSliceEncodingTask::FinishTask() {  WelsMutexLock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);  m_pCtx->pSliceThreading->bThreadBsBufferUsage[m_iThreadIdx] = false;  WelsMutexUnlock (&m_pCtx->pSliceThreading->mutexThreadBsBufferUsage);   WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,           "[MT] CWelsSliceEncodingTask()FinishTask for m_iSliceIdx %d, unlock thread %d",           m_iSliceIdx, m_iThreadIdx);   //sync multi-threading error  WelsMutexLock (&m_pCtx->mutexEncoderError);  if (ENC_RETURN_SUCCESS != m_eTaskResult) {    m_pCtx->iEncoderError |= m_eTaskResult;  }  WelsMutexUnlock (&m_pCtx->mutexEncoderError);} WelsErrorType CWelsSliceEncodingTask::ExecuteTask() { #if MT_DEBUG_BS_WR  m_pSliceBs->bSliceCodedFlag = false;#endif//MT_DEBUG_BS_WR  SSpatialLayerInternal* pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];  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);  assert (m_iSliceIdx == (int) m_pSlice->iSliceIdx);  int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType);  if (ENC_RETURN_SUCCESS != iReturn) {    return iReturn;  }  WelsUnloadNalForSlice (m_pSliceBs);   m_iSliceSize = 0;  iReturn      = WriteSliceBs (m_pCtx, m_pSliceBs, m_iSliceIdx, m_iSliceSize);  if (ENC_RETURN_SUCCESS != iReturn) {    WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,             "[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d",             pParamInternal->iCodingIndex,             m_iSliceIdx);    return iReturn;  }   m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (m_pCtx->pCurDqLayer, m_pCtx->pFuncList, m_pSlice);   WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL,           "@pSlice=%-6d sliceType:%c idc:%d size:%-6d",  m_iSliceIdx,           (m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'),           m_eNalRefIdc,           m_iSliceSize); #if MT_DEBUG_BS_WR  m_pSliceBs->bSliceCodedFlag = true;#endif//MT_DEBUG_BS_WR   return ENC_RETURN_SUCCESS;}  // CWelsLoadBalancingSlicingEncodingTaskWelsErrorType CWelsLoadBalancingSlicingEncodingTask::InitTask() {  WelsErrorType iReturn = CWelsSliceEncodingTask::InitTask();  if (ENC_RETURN_SUCCESS != iReturn) {    return iReturn;  }   m_iSliceStart = WelsTime();  WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,           "[MT] CWelsLoadBalancingSlicingEncodingTask()InitTask for m_iSliceIdx %d at time=%" PRId64,           m_iSliceIdx, m_iSliceStart);   return ENC_RETURN_SUCCESS;} void CWelsLoadBalancingSlicingEncodingTask::FinishTask() {  CWelsSliceEncodingTask::FinishTask();  SSpatialLayerInternal* pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];  m_pSlice->uiSliceConsumeTime = (uint32_t) (WelsTime() - m_iSliceStart);  WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,           "[MT] CWelsLoadBalancingSlicingEncodingTask()FinishTask, coding_idx %d, um_iSliceIdx %d, uiSliceConsumeTime %d, m_iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d at time=%"           PRId64,           pParamInternal->iCodingIndex,           m_iSliceIdx,           m_pSlice->uiSliceConsumeTime,           m_iSliceSize,           m_pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice,           m_pSlice->iCountMbNumInSlice,           (m_pSlice->uiSliceConsumeTime + m_iSliceStart));} //CWelsConstrainedSizeSlicingEncodingTaskWelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {   SDqLayer* pCurDq                        = m_pCtx->pCurDqLayer;  const int32_t kiSliceIdxStep            = m_pCtx->iActiveThreadsNum;  SSpatialLayerInternal* pParamInternal   = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];  const int32_t kiPartitionId             = m_iSliceIdx % kiSliceIdxStep;  const int32_t kiFirstMbInPartition      = pCurDq->FirstMbIdxOfPartition[kiPartitionId];  const int32_t kiEndMbIdxInPartition     = pCurDq->EndMbIdxOfPartition[kiPartitionId];  const int32_t kiCodedSliceNumByThread   = pCurDq->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum;  m_pSlice                                = &pCurDq->sSliceBufferInfo[m_iThreadIdx].pSliceBuffer[kiCodedSliceNumByThread];  m_pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice  = kiFirstMbInPartition;  int32_t iReturn      = 0;  bool bNeedReallocate = false;   int32_t iDiffMbIdx = kiEndMbIdxInPartition - kiFirstMbInPartition;  if (0 == iDiffMbIdx) {    m_pSlice->iSliceIdx = -1;    return ENC_RETURN_SUCCESS;  }   int32_t iAnyMbLeftInPartition = iDiffMbIdx + 1;  int32_t iLocalSliceIdx = m_iSliceIdx;  while (iAnyMbLeftInPartition > 0) {    bNeedReallocate = (pCurDq->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum                       >=  pCurDq->sSliceBufferInfo[m_iThreadIdx].iMaxSliceNum - 1) ? true : false;    if (bNeedReallocate) {      WelsMutexLock (&m_pCtx->pSliceThreading->mutexThreadSlcBuffReallocate);      //for memory statistic variable      iReturn = ReallocateSliceInThread (m_pCtx, pCurDq, m_pCtx->uiDependencyId, m_iThreadIdx);      WelsMutexUnlock (&m_pCtx->pSliceThreading->mutexThreadSlcBuffReallocate);      if (ENC_RETURN_SUCCESS != iReturn) {        return iReturn;      }    }     iReturn = InitOneSliceInThread (m_pCtx, m_pSlice, m_iThreadIdx, m_pCtx->uiDependencyId, iLocalSliceIdx);    WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)    m_pSliceBs = &m_pSlice->sSliceBs;    InitBits (&m_pSliceBs->sBsWrite, m_pSliceBs->pBsBuffer, m_pSliceBs->uiSize);     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);     assert (iLocalSliceIdx == (int) m_pSlice->iSliceIdx);    int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType);    if (ENC_RETURN_SUCCESS != iReturn) {      return iReturn;    }    WelsUnloadNalForSlice (m_pSliceBs);     iReturn    = WriteSliceBs (m_pCtx, m_pSliceBs, iLocalSliceIdx, m_iSliceSize);    if (ENC_RETURN_SUCCESS != iReturn) {      WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,               "[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, uiLocalSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d",               pParamInternal->iCodingIndex,               iLocalSliceIdx, m_pSliceBs->uiSize, m_iSliceSize, m_pSliceBs->sNalList[0].iPayloadSize);      return iReturn;    }    m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, m_pCtx->pFuncList, m_pSlice);     WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL,             "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n",             iLocalSliceIdx,             (m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'),             m_eNalRefIdc,             m_iSliceSize            );     WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,             "[MT] CWelsConstrainedSizeSlicingEncodingTask(), coding_idx %d, iPartitionId %d, m_iThreadIdx %d, iLocalSliceIdx %d, m_iSliceSize %d, ParamValidationExt(), invalid uiMaxNalSizeiEndMbInPartition %d, pCurDq->LastCodedMbIdxOfPartition[%d] %d\n",             pParamInternal->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize,             kiEndMbIdxInPartition, kiPartitionId, pCurDq->LastCodedMbIdxOfPartition[kiPartitionId]);     iAnyMbLeftInPartition = kiEndMbIdxInPartition - pCurDq->LastCodedMbIdxOfPartition[kiPartitionId];    iLocalSliceIdx += kiSliceIdxStep;    m_pCtx->pCurDqLayer->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum ++;  }   return ENC_RETURN_SUCCESS;}  CWelsUpdateMbMapTask::CWelsUpdateMbMapTask (WelsCommon::IWelsTaskSink* pSink, sWelsEncCtx* pCtx,    const int32_t iSliceIdx): CWelsBaseTask (pSink) {  m_pCtx = pCtx;  m_iSliceIdx = iSliceIdx;} CWelsUpdateMbMapTask::~CWelsUpdateMbMapTask() {} WelsErrorType CWelsUpdateMbMapTask::Execute() {  UpdateMbListNeighborParallel (m_pCtx->pCurDqLayer, m_pCtx->pCurDqLayer->sMbDataP, m_iSliceIdx);  return ENC_RETURN_SUCCESS;} }  

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t