1255 lines · 41.4 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__

	strcpy(pCfg->sTracePath, fpath);		// confirmed_safe_unsafe_usage

Lines 1–500 of 1255.

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