1233 lines · 42.6 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  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. * */ #include <assert.h>#include "welsEncoderExt.h"#include "welsCodecTrace.h"#include "typedefs.h"#include "wels_const.h"#include "utils.h"#include "macros.h" #include "crt_util_safe_x.h"	// Safe CRT routines like util for cross platforms#include "ref_list_mgr_svc.h" #include <time.h>#if defined(_WIN32) /*&& defined(_DEBUG)*/ #include <windows.h>#include <stdio.h>#include <stdarg.h>#include <sys/types.h>#include <sys/timeb.h>#else#include <sys/time.h>#endif namespace WelsSVCEnc { /* *	CWelsH264SVCEncoder class implementation */CWelsH264SVCEncoder::CWelsH264SVCEncoder()  :	m_pEncContext (NULL),#if defined(_WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__)    m_pWelsTrace (NULL),#endif    m_pSrcPicList (NULL),    m_iSrcListSize (0),    m_iMaxPicWidth (0),    m_iMaxPicHeight (0),    m_iCspInternal (0),    m_bInitialFlag (FALSE) {#ifdef REC_FRAME_COUNT  int32_t m_uiCountFrameNum = 0;#endif//REC_FRAME_COUNT #ifdef OUTPUT_BIT_STREAM  str_t strStreamFileName[1024] = { 0 };  //for .264  int32_t iBufferUsed = 0;  int32_t iBufferLeft = 1023;   str_t strLenFileName[1024] = { 0 }; //for .len  int32_t iBufferUsedSize = 0;  int32_t iBufferLeftSize = 1023;#endif//OUTPUT_BIT_STREAM #ifdef OUTPUT_BIT_STREAM  time_t tTime; #if defined( _WIN32 )#if defined(_MSC_VER)#if _MSC_VER>=1500  struct tm tTimeNow;#else  struct tm* tTimeNow;#endif//_MSC_VER>=1500#endif//_MSC_VER  struct _timeb tTimeb;   time (&tTime);#if defined(_MSC_VER)#if _MSC_VER>=1500  LOCALTIME (&tTimeNow, &tTime);#else  tTimeNow = LOCALTIME (&tTime);  if (NULL == tTimeNow)    return;#endif//_MSC_VER>=1500#endif//_MSC_VER  FTIME (&tTimeb);#elif defined( __GNUC__ )  struct tm* tTimeNow;  struct timeval tTimev;  time (&tTime);  tTimeNow = (struct tm*)localtime (&tTime);  gettimeofday (&tTimev, NULL);#endif//WIN32 #ifdef _WIN32#if defined(_MSC_VER)#if _MSC_VER>=1500  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft, iBufferLeft,      "enc_bs_0x%p_", (void*)this);  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, iBufferLeftSize, "enc_size_0x%p_", (void*)this);#else  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft,      "enc_bs_0x%p_", (void*)this);  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, "enc_size_0x%p_", (void*)this);#endif//_MSC_VER>=1500#endif//_MSC_VER#else  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft,      "/tmp/enc_bs_0x%p_", (void*)this);  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, "/tmp/enc_size_0x%p", (void*)this);#endif//WIN32    iBufferLeft -= iBufferUsed;  if (iBufferLeft > iBufferUsed) {#if defined(_GNUC__)    iBufferUsed += strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S", tTimeNow);#else#if defined(_MSC_VER)    iBufferUsed += strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S",#if _MSC_VER>=1500                             & tTimeNow#else                             tTimeNow#endif//_MSC_VER>=1500                            );#endif//_MSC_VER#endif//__GNUC__    iBufferLeft -= iBufferUsed;  }   iBufferLeftSize -= iBufferUsedSize;  if (iBufferLeftSize > iBufferUsedSize) {#if defined(_GNUC__)    iBufferUsedSize += strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S", tTimeNow);#else#if defined(_MSC_VER)    iBufferUsedSize += strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S",#if _MSC_VER>=1500                                 & tTimeNow#else                                 tTimeNow#endif//_MSC_VER>=1500                                );#endif//_MSC_VER#endif//__GNUC__    iBufferLeftSize -= iBufferUsedSize;  }   if (iBufferLeft > iBufferUsed) {#ifdef _WIN32#if defined(_MSC_VER)#if _MSC_VER>=1500    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, iBufferLeft, ".%03.3u.264", tTimeb.millitm);#else    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimeb.millitm);#endif//_MSC_VER>=1500#endif//_MSC_VER#else    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimev.tv_usec / 1000);#endif//WIN32    iBufferLeft -= iBufferUsed;  }   if (iBufferLeftSize > iBufferUsedSize) {#ifdef _WIN32#if defined(_MSC_VER)#if _MSC_VER>=1500    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, iBufferLeftSize, ".%03.3u.len",                                 tTimeb.millitm);#else    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimeb.millitm);#endif//_MSC_VER>=1500#endif//_MSC_VER#else    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimev.tv_usec / 1000);#endif//WIN32    iBufferLeftSize -= iBufferUsedSize;  } #if defined(__GNUC__)  m_pFileBs       = FOPEN (strStreamFileName,      "wb");  m_pFileBsSize	= FOPEN (strLenFileName, "wb");#else#if defined(_MSC_VER)#if _MSC_VER>=1500  FOPEN (&m_pFileBs, strStreamFileName,      "wb");  FOPEN (&m_pFileBsSize, strLenFileName, "wb");#else  m_pFileBs       = FOPEN (strStreamFileName,      "wb");  m_pFileBsSize	= FOPEN (strLenFileName, "wb");#endif//_MSC_VER>=1500#endif//_MSC_VER#endif//__GNUC__   m_bSwitch	= FALSE;  m_iSwitchTimes	= 0;#endif//OUTPUT_BIT_STREAM   InitEncoder();} CWelsH264SVCEncoder::~CWelsH264SVCEncoder() {  WelsLog (NULL, WELS_LOG_INFO, "CWelsH264SVCEncoder::~CWelsH264SVCEncoder()\n");#if defined(_WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__)   if (m_pWelsTrace != NULL) {    delete m_pWelsTrace;    m_pWelsTrace = NULL;  }#endif#ifdef REC_FRAME_COUNT  WelsLog (m_pEncContext, WELS_LOG_INFO,           "CWelsH264SVCEncoder::~CWelsH264SVCEncoder(), m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum,           m_iCspInternal);#endif #ifdef REC_FRAME_COUNT  m_uiCountFrameNum = 0;#endif//REC_FRAME_COUNT #ifdef OUTPUT_BIT_STREAM  if (m_pFileBs) {    fclose (m_pFileBs);    m_pFileBs = NULL;  }  if (m_pFileBsSize) {    fclose (m_pFileBsSize);    m_pFileBsSize = NULL;  }  m_bSwitch	= FALSE;  m_iSwitchTimes	= 0;#endif//OUTPUT_BIT_STREAM   Uninitialize();} void CWelsH264SVCEncoder::InitEncoder (void) {#if defined(_WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__) #ifdef REC_FRAME_COUNT  WelsLog (m_pEncContext, WELS_LOG_INFO,           "CWelsH264SVCEncoder::InitEncoder, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal);#endif   m_pWelsTrace	= new welsCodecTrace();  if (m_pWelsTrace != NULL) {    const int32_t iWelsTraceExistingFlag = m_pWelsTrace->WelsTraceModuleIsExist();    if (iWelsTraceExistingFlag) {      m_pWelsTrace->SetTraceLevel (WELS_LOG_DEFAULT);      WelsSetLogCallback (welsCodecTrace::CODEC_TRACE);    }  }   // initialization  WelsSetLogLevel (WELS_LOG_DEFAULT);	// no output, WELS_LOG_QUIET#endif} /* Interfaces override from ISVCEncoder */ /* *	SVC Encoder Initialization */int CWelsH264SVCEncoder::Initialize (SVCEncodingParam* argv, const INIT_TYPE iInitType) {  if (INIT_TYPE_PARAMETER_BASED != iInitType || NULL == argv) {    WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInitType= %d, argv= 0x%p\n",             iInitType, (void*)argv);    return cmInitParaError;  }   if (m_bInitialFlag) {    WelsLog (m_pEncContext, WELS_LOG_WARNING, "CWelsH264SVCEncoder::Initialize(), reinitialize, m_bInitialFlag= %d\n",             m_bInitialFlag);    Uninitialize();  }   SVCEncodingParam		sEncodingParam;  SWelsSvcCodingParam	sConfig (true);   memcpy (&sEncodingParam, argv, sizeof (SVCEncodingParam));	// confirmed_safe_unsafe_usage #ifdef REC_FRAME_COUNT  WelsLog (m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::Initialize, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n",           m_uiCountFrameNum, m_iCspInternal);  WelsLog (m_pEncContext, WELS_LOG_INFO,           "coding_param->iPicWidth= %d;coding_param->iPicHeight= %d;coding_param->iTargetBitrate= %d;coding_param->iRCMode= %d;coding_param->iTemporalLayerNum= %d;coding_param->iSpatialLayerNum= %d;coding_param->fFrameRate= %.6ff;coding_param->iInputCsp= %d;coding_param->iKeyPicCodingMode= %d;coding_param->uiIntraPeriod= %d;coding_param->bEnableSpsPpsIdAddition = %d;coding_param->bPrefixNalAddingCtrl = %d;coding_param->bEnableDenoise= %d;coding_param->bEnableBackgroundDetection= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableCropPic= %d;coding_param->bEnableLongTermReference= %d;coding_param->iLtrMarkPeriod= %d;\n",           sEncodingParam.iPicWidth,           sEncodingParam.iPicHeight,           sEncodingParam.iTargetBitrate,           sEncodingParam.iRCMode,           sEncodingParam.iTemporalLayerNum,           sEncodingParam.iSpatialLayerNum,           sEncodingParam.fFrameRate,           sEncodingParam.iInputCsp,           sEncodingParam.iKeyPicCodingMode,           sEncodingParam.iIntraPeriod,           sEncodingParam.bEnableSpsPpsIdAddition,           sEncodingParam.bPrefixNalAddingCtrl,           sEncodingParam.bEnableDenoise,           sEncodingParam.bEnableBackgroundDetection,           sEncodingParam.bEnableAdaptiveQuant,           sEncodingParam.bEnableCropPic,           sEncodingParam.bEnableLongTermReference,           sEncodingParam.iLtrMarkPeriod);  int32_t i = 0;  while (i < sEncodingParam.iSpatialLayerNum) {    SSpatialLayerConfig* spatial_cfg = &sEncodingParam.sSpatialLayers[i];    WelsLog (m_pEncContext, WELS_LOG_INFO,             "coding_param->sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iQualityLayerNum= %d; .iSpatialBitrate= %d; .iCgsSnrRefined= %d; .iInterSpatialLayerPredFlag= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.uiSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\n",             i, spatial_cfg->iVideoWidth,             spatial_cfg->iVideoHeight,             spatial_cfg->fFrameRate,             spatial_cfg->iQualityLayerNum,             spatial_cfg->iSpatialBitrate,             spatial_cfg->iCgsSnrRefined,             spatial_cfg->iInterSpatialLayerPredFlag,             spatial_cfg->sSliceCfg.uiSliceMode,             spatial_cfg->sSliceCfg.sSliceArgument.uiSliceNum,             spatial_cfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint            );    ++ i;  }#endif//REC_FRAME_COUNT   // Convert SVCEncodingParam into WelsSVCParamConfig here..  if (sConfig.ParamTranscode (sEncodingParam, true)) {    WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), parameter_translation failed.\n");    Uninitialize();    return cmInitParaError;  }   m_iSrcListSize  = 1;   return Initialize ((void*)&sConfig, INIT_TYPE_CONFIG_BASED);} int CWelsH264SVCEncoder::Initialize (void* argv, const INIT_TYPE iInitType) {  if (INIT_TYPE_CONFIG_BASED != iInitType || NULL == argv) {    WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInitType= %d, argv= 0x%p.\n",             iInitType, (void*)argv);    return cmInitParaError;  }   if (m_bInitialFlag) {    WelsLog (m_pEncContext, WELS_LOG_WARNING, "CWelsH264SVCEncoder::Initialize(), reinitialize, m_bInitialFlag= %d.\n",             m_bInitialFlag);    Uninitialize();  }   SWelsSvcCodingParam*  pCfg = static_cast<SWelsSvcCodingParam*> (argv);   const int32_t iColorspace = pCfg->iInputCsp;  if (0 == iColorspace) {    WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInputCsp= %d.\n", iColorspace);    Uninitialize();    return cmInitParaError;  }   // Check valid parameters  const int32_t iNumOfLayers = pCfg->iNumDependencyLayer;  if (iNumOfLayers < 1 || iNumOfLayers > MAX_DEPENDENCY_LAYER) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid iNumDependencyLayer= %d, valid at range of [1, %d].\n", iNumOfLayers,             MAX_DEPENDENCY_LAYER);    Uninitialize();    return cmInitParaError;  }  if (pCfg->iNumTemporalLayer < 1)    pCfg->iNumTemporalLayer	= 1;  if (pCfg->iNumTemporalLayer > MAX_TEMPORAL_LEVEL) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid iNumTemporalLayer= %d, valid at range of [1, %d].\n",             pCfg->iNumTemporalLayer, MAX_TEMPORAL_LEVEL);    Uninitialize();    return cmInitParaError;  }   //	assert( cfg.uiGopSize >= 1 && ( cfg.uiIntraPeriod && (cfg.uiIntraPeriod % cfg.uiGopSize) == 0) );   if (pCfg->uiGopSize < 1 || pCfg->uiGopSize > MAX_GOP_SIZE) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid uiGopSize= %d, valid at range of [1, %d].\n", pCfg->uiGopSize,             MAX_GOP_SIZE);    Uninitialize();    return cmInitParaError;  }   if (!WELS_POWER2_IF (pCfg->uiGopSize)) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid uiGopSize= %d, valid at range of [1, %d] and yield to power of 2.\n",             pCfg->uiGopSize, MAX_GOP_SIZE);    Uninitialize();    return cmInitParaError;  }   if (pCfg->uiIntraPeriod && pCfg->uiIntraPeriod < pCfg->uiGopSize) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid uiIntraPeriod= %d, valid in case it equals to 0 for unlimited intra period or exceeds specified uiGopSize= %d.\n",             pCfg->uiIntraPeriod, pCfg->uiGopSize);    Uninitialize();    return cmInitParaError;  }   if ((pCfg->uiIntraPeriod && (pCfg->uiIntraPeriod & (pCfg->uiGopSize - 1)) != 0)) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), invalid uiIntraPeriod= %d, valid in case it equals to 0 for unlimited intra period or exceeds specified uiGopSize= %d also multiple of it.\n",             pCfg->uiIntraPeriod, pCfg->uiGopSize);    Uninitialize();    return cmInitParaError;  }   // Fine tune num_ref_num  if (pCfg->bEnableLongTermReference) {    pCfg->iLTRRefNum = LONG_TERM_REF_NUM;  } else {    pCfg->iLTRRefNum = 0;  }  pCfg->iNumRefFrame = ((pCfg->uiGopSize >> 1) > 1) ? ((pCfg->uiGopSize >> 1) + pCfg->iLTRRefNum) :                       (MIN_REF_PIC_COUNT + pCfg->iLTRRefNum);   pCfg->iNumRefFrame = WELS_CLIP3 (pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);   if (pCfg->uiLtrMarkPeriod == 0) {    pCfg->uiLtrMarkPeriod = 30;  }   const int32_t kiDecStages = WELS_LOG2 (pCfg->uiGopSize);  pCfg->iInputCsp			= iColorspace;  pCfg->iNumTemporalLayer	= (int8_t) (1 + kiDecStages);  pCfg->iLoopFilterAlphaC0Offset	= WELS_CLIP3 (pCfg->iLoopFilterAlphaC0Offset, -6, 6);  pCfg->iLoopFilterBetaOffset		= WELS_CLIP3 (pCfg->iLoopFilterBetaOffset, -6, 6); //	m_pSrcPicList	= (SSourcePicture **)WelsMalloc( pCfg->iNumDependencyLayer * sizeof(SSourcePicture *), "m_pSrcPicList" );  // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)  m_pSrcPicList	= new SSourcePicture* [iNumOfLayers];   if (NULL == m_pSrcPicList) {    WelsLog (m_pEncContext, WELS_LOG_ERROR,             "CWelsH264SVCEncoder::Initialize(), pOut of memory due m_pSrcPicList memory request.\n");    Uninitialize();    return cmMallocMemeError;  }   // decide property list size between INIT_TYPE_PARAMETER_BASED/INIT_TYPE_CONFIG_BASED  m_iMaxPicWidth	= pCfg->iActualPicWidth;  m_iMaxPicHeight	= pCfg->iActualPicHeight;  m_iSrcListSize  = iNumOfLayers;   for (int32_t i = 0; i < m_iSrcListSize; ++ i) {//		m_pSrcPicList[i]	= (SSourcePicture *)WelsMalloc( sizeof(SSourcePicture), "m_pSrcPicList[]" );    // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)    m_pSrcPicList[i]	= new SSourcePicture;     if (NULL == m_pSrcPicList[i]) {      WelsLog (m_pEncContext, WELS_LOG_ERROR,               "CWelsH264SVCEncoder::Initialize(), pOut of memory due m_pSrcPicList[%d] memory request.\n", i);      Uninitialize();      m_iSrcListSize = 0;      return cmMallocMemeError;    }    InitPic (m_pSrcPicList[i], iColorspace, m_iMaxPicWidth, m_iMaxPicHeight);  } #if defined(OUTPUT_BIT_STREAM) || defined(ENABLE_TRACE_FILE)  str_t fpath[MAX_FNAME_LEN] = {0};#if defined(__GNUC__)  SNPRINTF (fpath, MAX_FNAME_LEN, "/tmp/");		// confirmed_safe_unsafe_usage #else//__GNUC__ #if defined (_MSC_VER)#if _MSC_VER>=1500  SNPRINTF (fpath, MAX_FNAME_LEN, MAX_FNAME_LEN, ".\\");		// confirmed_safe_unsafe_usage#else  SNPRINTF (fpath, MAX_FNAME_LEN, ".\\");		// confirmed_safe_unsafe_usage#endif//_MSC_VER>=1500#endif//_MSC_VER#endif //__GNUC__ 

Lines 1–500 of 1233.

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