Ethan HuggInitial Commit70e5e6212 years agoHistory
2106 lines · 72.2 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. * *	decoder_core.c:	Wels decoder framework core implementation */ #include <string.h>#include "codec_def.h"#include "decoder_core.h"#include "typedefs.h"#include "wels_const.h"#include "wels_common_basis.h"#include "codec_app_def.h"#include "decoder_context.h"#include "dec_golomb.h"#include "bit_stream.h"#include "error_code.h"#include "parameter_sets.h"#include "fmo.h"#include "utils.h"#include "memmgr_nal_unit.h"#include "dec_frame.h"#include "au_parser.h"#include "pic_queue.h"#include "ls_defines.h"#include "decode_slice.h"#include "manage_dec_ref.h"#include "expand_pic.h"#include "decoder.h"#include "decode_mb_aux.h"#include "mem_align.h" namespace WelsDec { static inline int32_t DecodeFrameConstruction( PWelsDecoderContext pCtx, uint8_t **ppDst, int32_t *pDstLen, int32_t *pWidth, int32_t *pHeight, SBufferInfo *pDstInfo ){	PDqLayer pCurDq = pCtx->pCurDqLayer;		PPicture pPic = pCtx->pDec; 	const int32_t kiWidth = pCurDq->iMbWidth << 4;	const int32_t kiHeight= pCurDq->iMbHeight << 4; 	const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight; 	if ( pPic->iTotalNumMbRec != kiTotalNumMbInCurLayer )	{		WelsLog( pCtx, WELS_LOG_WARNING, "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",			pPic->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight );		return -1;	}#ifdef NO_WAITING_AU    pPic->iTotalNumMbRec = 0;#endif 	if ( I_SLICE == pCurDq->sLayerInfo.sSliceInLayer.eSliceType )	{		memcpy( &(pCtx->sFrameCrop), &(pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop), sizeof(SPosOffset) );//confirmed_safe_unsafe_usage#ifdef LONG_TERM_REF		pCtx->bParamSetsLostFlag      = false;#else		pCtx->bReferenceLostAtT0Flag = false;	// need initialize it due I_SLICE, 6/4/2010#endif //LONG_TERM_REF		WelsLog( pCtx, WELS_LOG_INFO, "DecodeFrameConstruction()::::output good I frame, %d x %d, crop_left:%d, crop_right:%d, crop_top:%d, crop_bottom:%d.\n",			kiWidth, kiHeight, pCtx->sFrameCrop.iLeftOffset, pCtx->sFrameCrop.iRightOffset, pCtx->sFrameCrop.iTopOffset, pCtx->sFrameCrop.iBottomOffset );		WelsLog( pCtx, WELS_LOG_INFO, "After decoding, set_mode:[%s], eWorkMode:[%s], eBufferProperty:[%s]\n",			DECODER_MODE_NAME(pCtx->iSetMode), DECODER_MODE_NAME(pCtx->iDecoderMode), OUTPUT_PROPERTY_NAME(pDstInfo->eBufferProperty));	}		//////output:::normal path	ppDst[0]      = pPic->pData[0];	ppDst[1]      = pPic->pData[1];	ppDst[2]      = pPic->pData[2];	*pDstLen     = pPic->iLinesize[0]; 	*(pDstLen+1) = pPic->iLinesize[1];	*pWidth      = kiWidth;	*pHeight     = kiHeight; 	pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420; 	pDstInfo->UsrData.sSystemBuffer.iWidth = kiWidth - (pCtx->sFrameCrop.iLeftOffset + pCtx->sFrameCrop.iRightOffset)*2;	pDstInfo->UsrData.sSystemBuffer.iHeight = kiHeight - (pCtx->sFrameCrop.iTopOffset + pCtx->sFrameCrop.iBottomOffset)*2;	pDstInfo->UsrData.sSystemBuffer.iStride[0] = pPic->iLinesize[0];	pDstInfo->UsrData.sSystemBuffer.iStride[1] = pPic->iLinesize[1];	ppDst[0] = ppDst[0] + pCtx->sFrameCrop.iTopOffset*2*pPic->iLinesize[0] + pCtx->sFrameCrop.iLeftOffset*2;	ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset  *pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;	ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset  *pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;	pDstInfo->eBufferProperty = BUFFER_HOST;	pDstInfo->iBufferStatus = 1; 	return 0;} inline BOOL_T    CheckSliceNeedReconstruct(int16_t iCurDid, int16_t iCurQid, bool_t bStoreRefBasePicFlag, 	uint8_t uiDidMax, uint8_t uiLayerDqId, uint8_t uiTargetDqId){    return ( (iCurDid == uiDidMax) && (iCurQid == BASE_QUALITY_ID) && (bStoreRefBasePicFlag) ) // store base       || (uiLayerDqId == uiTargetDqId); // target layer} inline uint8_t GetTargetDqId(uint8_t uiTargetDqId,  SDecodingParam * psParam){    uint8_t  uiRequiredDqId = psParam ? psParam->uiTargetDqLayer : (uint8_t)255; 	return WELS_MIN(uiTargetDqId, uiRequiredDqId);}	 inline void_t    HandleReferenceLostL0(PWelsDecoderContext pCtx, PNalUnit pCurNal){    if( 0 == pCurNal->sNalHeaderExt.uiTemporalId ){		pCtx->bReferenceLostAtT0Flag = true;    }#ifndef LONG_TERM_REF	if( pCtx->bReferenceLostAtT0Flag ){		ResetParameterSetsState(pCtx);	}	#endif	pCtx->iErrorCode |= dsBitstreamError;} inline void_t    HandleReferenceLost(PWelsDecoderContext pCtx, PNalUnit pCurNal){    if( (0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId) ){		pCtx->bReferenceLostAtT0Flag = true;    }#ifndef LONG_TERM_REF	if( pCtx->bReferenceLostAtT0Flag ){		ResetParameterSetsState(pCtx);    }#endif	pCtx->iErrorCode |= dsRefLost;} inline int32_t  WelsDecodeConstructSlice(PWelsDecoderContext pCtx, PNalUnit pCurNal){    int32_t  iRet = WelsTargetSliceConstruction(pCtx); 	if( iRet ){		HandleReferenceLostL0(pCtx, pCurNal);	} 	return iRet;} /* *	Predeclared function routines .. */int32_t ParseRefPicListReordering ( PBitStringAux pBs, PSliceHeader pSh ){	int32_t iList = 0;	const ESliceType keSt = pSh->eSliceType;	PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;		if ( keSt == I_SLICE || keSt == SI_SLICE )		return ERR_NONE; 	// Common syntaxs for P or B slices: list0, list1 followed if B slices used.	do {		pRefPicListReordering->bRefPicListReorderingFlag[iList]	= !!BsGetOneBit( pBs); 		if ( pRefPicListReordering->bRefPicListReorderingFlag[iList] ){			int32_t iIdx = 0;			do {				const uint8_t kuiIdc = BsGetUe( pBs );									//Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---				if ((iIdx >= MAX_REF_PIC_COUNT )||(kuiIdc > 3))				{					return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);				}				pRefPicListReordering->sReorderingSyn[iList][iIdx].uiReorderingOfPicNumsIdc	= kuiIdc;				if ( kuiIdc == 3 )					break; 				if ( iIdx >= pSh->uiRefCount[iList] || iIdx >= MAX_REF_PIC_COUNT )					return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);								if (kuiIdc == 0 || kuiIdc == 1){					pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = BsGetUe( pBs );	// uiAbsDiffPicNumMinus1				}				else if (kuiIdc == 2){									pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum= BsGetUe( pBs );							}								++ iIdx;			} while(true);		}		if (keSt != B_SLICE)			break;		++ iList;	} while(iList < LIST_A);		return ERR_NONE;} int32_t ParseDecRefPicMarking ( PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps, const bool_t kbIdrFlag){	PRefPicMarking const kpRefMarking = &pSh->sRefMarking; 	if ( kbIdrFlag ){		kpRefMarking->bNoOutputOfPriorPicsFlag	= !!BsGetOneBit( pBs );		kpRefMarking->bLongTermRefFlag			= !!BsGetOneBit( pBs );	}	else{		kpRefMarking->bAdaptiveRefPicMarkingModeFlag	= !!BsGetOneBit( pBs );		if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag){			int32_t iIdx = 0;			do {				const int32_t kiMmco = BsGetUe( pBs ); 				kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kiMmco;				if (kiMmco == MMCO_END)					break; 				if (kiMmco == MMCO_SHORT2UNUSED || kiMmco == MMCO_SHORT2LONG)				{					kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + BsGetUe( pBs );					kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((1<<pSps->uiLog2MaxFrameNum)-1);				}				else if (kiMmco == MMCO_LONG2UNUSED)					kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = BsGetUe( pBs ); 				if (kiMmco == MMCO_SHORT2LONG || kiMmco == MMCO_LONG)				{					kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = BsGetUe( pBs );				}				else if (kiMmco == MMCO_SET_MAX_LONG)					kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + BsGetUe( pBs );				++ iIdx; 			} while(iIdx < MAX_MMCO_COUNT);		}		}		return ERR_NONE;} bool_t FillDefaultSliceHeaderExt ( PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalExt ){	if ( pShExt == NULL || pNalExt == NULL )		return false; 	if ( pNalExt->iNoInterLayerPredFlag || pNalExt->uiQualityId > 0 )		pShExt->bBasePredWeightTableFlag	= false;	else		pShExt->bBasePredWeightTableFlag	= true;    pShExt->uiRefLayerDqId = (uint8_t)-1;	pShExt->uiDisableInterLayerDeblockingFilterIdc	= 0;	pShExt->iInterLayerSliceAlphaC0Offset			= 0;	pShExt->iInterLayerSliceBetaOffset				= 0;	pShExt->bConstrainedIntraResamplingFlag			= false;	pShExt->uiRefLayerChromaPhaseXPlus1Flag			= 0;	pShExt->uiRefLayerChromaPhaseYPlus1				= 1;	//memset(&pShExt->sScaledRefLayer, 0, sizeof(SPosOffset)); 	pShExt->iScaledRefLayerPicWidthInSampleLuma	= pShExt->sSliceHeader.iMbWidth << 4;	pShExt->iScaledRefLayerPicHeightInSampleLuma	= pShExt->sSliceHeader.iMbHeight << 4; 	pShExt->bSliceSkipFlag	= false;	pShExt->bAdaptiveBaseModeFlag	= false;	pShExt->bDefaultBaseModeFlag	= false;	pShExt->bAdaptiveMotionPredFlag	= false;	pShExt->bDefaultMotionPredFlag	= false;	pShExt->bAdaptiveResidualPredFlag	= false;	pShExt->bDefaultResidualPredFlag	= false;	pShExt->bTCoeffLevelPredFlag		= false;	pShExt->uiScanIdxStart				= 0;	pShExt->uiScanIdxEnd				= 15; 	return true;} /* * WelsInitMemory * Memory request for new introduced data * Especially for: * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache. * return: *	0 - success; otherwise returned error_no defined in error_no.h.*/int32_t WelsInitMemory( PWelsDecoderContext pCtx ){	if (pCtx == NULL){		return ERR_INFO_INVALID_PTR;	} 	if ( MemInitNalList( &pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU ) != 0 )		return ERR_INFO_OUT_OF_MEMORY;	 	if ( ( pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc( MAX_ACCESS_UINT_CAPACITY, "pCtx->sRawData->pHead" )) ) == NULL )	{		return ERR_INFO_OUT_OF_MEMORY;	}	pCtx->sRawData.pStartPos               =	pCtx->sRawData.pCurPos                 = pCtx->sRawData.pHead;	pCtx->sRawData.pEnd                     = pCtx->sRawData.pHead + MAX_ACCESS_UINT_CAPACITY;			pCtx->uiTargetDqId			= (uint8_t)-1;	pCtx->bEndOfStreamFlag	= false;	pCtx->iImgWidthInPixel	= 0;	pCtx->iImgHeightInPixel	= 0;			return ERR_NONE;} /* * WelsFreeMemory * Free memory introduced in WelsInitMemory at destruction of decoder. *  */void_t WelsFreeMemory( PWelsDecoderContext pCtx ){	if ( pCtx == NULL )		return; 	if ( NULL != pCtx->pParam )	{		WelsFree( pCtx->pParam, "pCtx->pParam" ); 		pCtx->pParam = NULL;	} 	MemFreeNalList( &pCtx->pAccessUnitList );				if ( pCtx->sRawData.pHead )	{		WelsFree(pCtx->sRawData.pHead, "pCtx->sRawData->pHead");			}	pCtx->sRawData.pHead                = NULL;	pCtx->sRawData.pEnd                 = NULL;	pCtx->sRawData.pStartPos	        = NULL;	pCtx->sRawData.pCurPos             = NULL;	} /* *	DecodeNalHeaderExt *	Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT *	Parameter: *	pNal:	target NALUnit ptr *	pSrc:	NAL Unit bitstream */void_t DecodeNalHeaderExt( PNalUnit pNal, uint8_t* pSrc ){	PNalUnitHeaderExt pHeaderExt = &pNal->sNalHeaderExt;	 	uint8_t uiCurByte = *pSrc;		pHeaderExt->bIdrFlag				 = !!(uiCurByte & 0x40);	pHeaderExt->uiPriorityId			 = uiCurByte & 0x3F; 	uiCurByte = *(++pSrc);	pHeaderExt->iNoInterLayerPredFlag = uiCurByte >> 7;	pHeaderExt->uiDependencyId			 = (uiCurByte & 0x70) >> 4;	pHeaderExt->uiQualityId				 = uiCurByte & 0x0F;	uiCurByte = *(++pSrc);	pHeaderExt->uiTemporalId			 = uiCurByte >> 5;	pHeaderExt->bUseRefBasePicFlag	     = !!(uiCurByte & 0x10);	pHeaderExt->bDiscardableFlag		 = !!(uiCurByte & 0x08);	pHeaderExt->bOutputFlag				 = !!(uiCurByte & 0x04);	pHeaderExt->uiReservedThree2Bits	 = uiCurByte & 0x03;		pHeaderExt->uiLayerDqId				 = (pHeaderExt->uiDependencyId << 4) | pHeaderExt->uiQualityId;}  #ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_IDint32_t CheckPpsId( PWelsDecoderContext pCtx, PPps* ppPps, uint32_t uiPpsId ){	PPps pPpsList = pCtx->sPpsBuffer;	int32_t iPpsNum = pCtx->iPpsTotalNum;	int32_t i = 0; 	if ( iPpsNum <= 0 )	{		pCtx->iErrorCode |= dsNoParamSets;				WelsLog( pCtx, WELS_LOG_WARNING, "CheckPpsId():::::PPS list is empty...NO PPS!!!\n" );		return dsNoParamSets;	} 	while ( i < iPpsNum )	{		if ( uiPpsId == pPpsList[i].iPpsId )		{			*ppPps = &pPpsList[i];			break;		}		else		{			++i;		}	} 	if ( i == iPpsNum )	{		pCtx->iErrorCode |= dsNoParamSets;				WelsLog( pCtx, WELS_LOG_WARNING, "CheckPpsId()::::::CAN NOT find the matching from the PPS List.  iPpsId:%d\n", uiPpsId );		return dsNoParamSets;	} 	return 0;} int32_t CheckSpsId( PWelsDecoderContext pCtx, PSubsetSps* ppSubsetSps, PSps* ppSps, int32_t iSpsId, bool_t bExtensionFlag ){	PSps pSpsList = pCtx->sSpsBuffer;	PSubsetSps pSubspsList = pCtx->sSubsetSpsBuffer; 	int32_t iSpsNum    = pCtx->iSpsTotalNum;	int32_t iSubspsNum = pCtx->iSubspsTotalNum;	int32_t i = 0; 	if ( bExtensionFlag )	{		if ( iSubspsNum <= 0 )		{			pCtx->iErrorCode |= dsNoParamSets;						WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::SUBSPS list is empty....NO SUBSPS\n" );			return dsNoParamSets;		}		while ( i < iSubspsNum )		{			if ( iSpsId == pSubspsList[i].sSps.iSpsId )			{				*ppSubsetSps = &pSubspsList[i];				*ppSps       = &pSubspsList[i].sSps;				break;			}			else			{				++i;			}		}		if ( i == iSubspsNum )		{			pCtx->iErrorCode |= dsNoParamSets;						WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::::CAN NOT find the matching from the SUBSPS List.  iSpsId:%d\n", iSpsId );			return dsNoParamSets;		}	}	else	{		if ( iSpsNum <= 0 )		{			pCtx->iErrorCode |= dsNoParamSets;						WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::SPS list is empty....NO SPS\n" );			return dsNoParamSets;		}		while ( i < iSpsNum )		{			if ( iSpsId == pSpsList[i].iSpsId )			{				*ppSubsetSps = NULL;				*ppSps       = &pSpsList[i];				break;			}			else			{				++i;			}		}		if ( i == iSpsNum )		{			pCtx->iErrorCode |= dsNoParamSets;						WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::::CAN NOT find the matching from the SPS List.  iSpsId:%d\n", iSpsId );			return dsNoParamSets;		}	}		return 0;

Lines 1–500 of 2106.

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