Ethan HuggInitial Commit70e5e6212 years agoHistory
532 lines · 14.3 KB · C++
RawDownload
/*! * \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 "mem_align.h"#include "utils.h" //#include "macros.h"#include "decoder.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 <sys/timeb.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/***************************************************************************/CWelsDecoder::CWelsDecoder(void_t):	m_pDecContext( NULL ),	m_pTrace( NULL ){#ifdef OUTPUT_BIT_STREAM	str_t chFileName[1024] = { 0 };  //for .264	int iBufUsed = 0;	int iBufLeft = 1023; 	str_t chFileNameSize[1024] = { 0 }; //for .len	int iBufUsedSize = 0;	int iBufLeftSize = 1023;#endif//OUTPUT_BIT_STREAM  	m_pTrace = CreateWelsTrace(Wels_Trace_Type);	 	IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO,"CWelsDecoder::CWelsDecoder() entry");   	#ifdef OUTPUT_BIT_STREAM    SWelsTime sCurTime; 	WelsGetTimeOfDay(&sCurTime);			iBufUsed      += WelsSnprintf(chFileName,  iBufLeft,  "bs_0x%p_", (void_t*)this);	iBufUsedSize += WelsSnprintf(chFileNameSize, iBufLeftSize, "size_0x%p_", (void_t*)this); 	iBufLeft -= iBufUsed;	if ( iBufLeft > iBufUsed )	{		iBufUsed += WelsStrftime(&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);		iBufLeft -= iBufUsed;	} 	iBufLeftSize -= iBufUsedSize;	if ( iBufLeftSize> iBufUsedSize )	{			iBufUsedSize += WelsStrftime(&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);		iBufLeftSize -= iBufUsedSize;	} 	if ( iBufLeft > iBufUsed )	{		iBufUsed += WelsSnprintf(&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillsecond(&sCurTime));		iBufLeft -= iBufUsed;	} 	if ( iBufLeftSize > iBufUsedSize )	{        iBufUsedSize += WelsSnprintf(&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len", WelsGetMillsecond(&sCurTime));		iBufLeftSize -= iBufUsedSize;	}	 	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(){			IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()"); 	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( NULL != m_pTrace ){		delete m_pTrace;		m_pTrace = NULL;	}	} long CWelsDecoder::Initialize(void_t* pParam, const INIT_TYPE keInitType){	if ( pParam == NULL || keInitType != INIT_TYPE_PARAMETER_BASED ){		IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::Initialize(), invalid input argument.");		return cmInitParaError;	} 	// H.264 decoder initialization,including memory allocation,then open it ready to decode	InitDecoder(); 	DecoderConfigParam( m_pDecContext, pParam );		return cmResultSuccess;} long CWelsDecoder::Unintialize(){	UninitDecoder();		return ERR_NONE;} void_t CWelsDecoder::UninitDecoder( void_t ){	if ( NULL == m_pDecContext )		return;		IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "into CWelsDecoder::uninit_decoder().."); 	WelsEndDecoder( m_pDecContext ); 	if ( NULL != m_pDecContext )	{		WelsFree( m_pDecContext, "m_pDecContext" ); 		m_pDecContext	= NULL;	} 	IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "left CWelsDecoder::uninit_decoder()..");} // the return value of this function is not suitable, it need report failure info to upper layer.void_t CWelsDecoder::InitDecoder( void_t ){	IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder()..");	 	m_pDecContext	= (PWelsDecoderContext)WelsMalloc( sizeof(SWelsDecoderContext), "m_pDecContext" );		WelsInitDecoder( m_pDecContext, m_pTrace, IWelsTrace::WelsTrace ); 	IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder().. left");} /* * Set Option	 */long CWelsDecoder::SetOption(DECODER_OPTION eOptID, void_t* pOption){	int iVal = 0;		if ( m_pDecContext == NULL )		return dsInitialOptExpected;		if ( eOptID == DECODER_OPTION_DATAFORMAT ) // Set color space of decoding output frame	{				if ( pOption == NULL )			return cmInitParaError;				iVal = *((int*)pOption);	// is_rgb				return DecoderSetCsp( m_pDecContext, iVal );	}	else 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 		m_pDecContext->bEndOfStreamFlag	= iVal ? true : false;				return cmResultSuccess;	}	else if ( eOptID == DECODER_OPTION_MODE)	{		if ( pOption == NULL )			return cmInitParaError; 		iVal = *((int *)pOption); 		m_pDecContext->iSetMode = iVal;		if(iVal == SW_MODE)		{			m_pDecContext->iDecoderOutputProperty = BUFFER_HOST;		}		else		{#if !defined(__APPLE__)			m_pDecContext->iDecoderOutputProperty = BUFFER_DEVICE;#else			m_pDecContext->iDecoderOutputProperty = BUFFER_HOST;//BUFFER_HOST;//BUFFER_DEVICE;#endif					}				return cmResultSuccess;	}	else if ( eOptID == DECODER_OPTION_OUTPUT_PROPERTY)	{		if ( pOption == NULL)			return cmInitParaError; 		iVal = *((int *)pOption);		if( m_pDecContext->iSetMode != SW_MODE)				m_pDecContext->iDecoderOutputProperty = iVal;	}  	return cmInitParaError;} /* *	Get Option */long CWelsDecoder::GetOption(DECODER_OPTION eOptID, void_t* pOption){	int iVal = 0;		if ( m_pDecContext == NULL )		return cmInitExpected;		if ( pOption == NULL )		return cmInitParaError;		if ( DECODER_OPTION_DATAFORMAT == eOptID ){		iVal = m_pDecContext->iOutputColorFormat;		*((int*)pOption)	= iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_END_OF_STREAM == eOptID ){		iVal	= m_pDecContext->bEndOfStreamFlag;		*((int*)pOption)	= iVal;		return cmResultSuccess;	}#ifdef LONG_TERM_REF	else if ( DECODER_OPTION_IDR_PIC_ID == eOptID ){		iVal = m_pDecContext->uiCurIdrPicId;		*((int*)pOption) = iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_FRAME_NUM == eOptID)	{		iVal = m_pDecContext->iFrameNum;		*((int*)pOption) = iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_LTR_MARKING_FLAG == eOptID )	{		iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;		*((int*)pOption) = iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID )	{		iVal = m_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 = m_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 = m_pDecContext->iFeedbackTidInAu;		*((int*)pOption) = iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_MODE == eOptID )	{		if ( pOption == NULL )			return cmInitParaError;				iVal = m_pDecContext->iSetMode;				*((int *)pOption) = iVal;		return cmResultSuccess;	}	else if ( DECODER_OPTION_DEVICE_INFO == eOptID )	{		if ( pOption == NULL )			return cmInitParaError; 		return cmResultSuccess;	}		return cmInitParaError;} DECODING_STATE CWelsDecoder::DecodeFrame(	const unsigned char* kpSrc,											const int kiSrcLen,												void_t ** ppDst,											SBufferInfo* pDstInfo){	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		m_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. 		m_pDecContext->bEndOfStreamFlag = true;	}			ppDst[0] = ppDst[1] = ppDst[2] = NULL;	m_pDecContext->iErrorCode             = dsErrorFree; //initialize at the starting of AU decoding.	m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize	memset(pDstInfo,0,sizeof(SBufferInfo));	pDstInfo->eBufferProperty = (EBufferProperty)m_pDecContext->iDecoderOutputProperty; #ifdef LONG_TERM_REF	m_pDecContext->bReferenceLostAtT0Flag       = false; //initialize for LTR	m_pDecContext->bCurAuContainLtrMarkSeFlag = false;	m_pDecContext->iFrameNumOfAuMarkedLtr      = 0;	m_pDecContext->iFrameNum                       = -1; //initialize#endif 	m_pDecContext->iFeedbackTidInAu             = -1; //initialize		WelsDecodeBs( m_pDecContext, kpSrc, kiSrcLen, (unsigned char**)ppDst, pDstInfo); //iErrorCode has been modified in this function		pDstInfo->eWorkMode = (EDecodeMode)m_pDecContext->iDecoderMode; 	if ( m_pDecContext->iErrorCode )	{				ENalUnitType eNalType = NAL_UNIT_UNSPEC_0;	//for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently		 		eNalType	= m_pDecContext->sCurNalHead.eNalUnitType;				//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 == m_pDecContext->eVideoType) )		{#ifdef LONG_TERM_REF			m_pDecContext->bParamSetsLostFlag = true;#else			m_pDecContext->bReferenceLostAtT0Flag = true;#endif			ResetParameterSetsState( m_pDecContext ); //initial SPS&PPS ready flag		}		 		IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);		return (DECODING_STATE)m_pDecContext->iErrorCode;	} 	return dsErrorFree;} 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;	DstInfo.eBufferProperty = BUFFER_HOST; 	eDecState = DecodeFrame(kpSrc, kiSrcLen, (void_t **)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;}  } // namespace WelsDec  using namespace WelsDec; 

Lines 1–500 of 532.

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